aboutsummaryrefslogtreecommitdiff
path: root/doc/handbook/chapters/developer.texi
diff options
context:
space:
mode:
Diffstat (limited to 'doc/handbook/chapters/developer.texi')
-rw-r--r--doc/handbook/chapters/developer.texi10157
1 files changed, 0 insertions, 10157 deletions
diff --git a/doc/handbook/chapters/developer.texi b/doc/handbook/chapters/developer.texi
deleted file mode 100644
index cf13fd816..000000000
--- a/doc/handbook/chapters/developer.texi
+++ /dev/null
@@ -1,10157 +0,0 @@
1@c ***********************************************************************
2@node GNUnet Developer Handbook
3@chapter GNUnet Developer Handbook
4
5This book is intended to be an introduction for programmers that want to
6extend the GNUnet framework. GNUnet is more than a simple peer-to-peer
7application.
8
9For developers, GNUnet is:
10
11@itemize @bullet
12@item developed by a community that believes in the GNU philosophy
13@item Free Software (Free as in Freedom), licensed under the
14GNU Affero General Public License
15(@uref{https://www.gnu.org/licenses/licenses.html#AGPL})
16@item A set of standards, including coding conventions and
17architectural rules
18@item A set of layered protocols, both specifying the communication
19between peers as well as the communication between components
20of a single peer
21@item A set of libraries with well-defined APIs suitable for
22writing extensions
23@end itemize
24
25In particular, the architecture specifies that a peer consists of many
26processes communicating via protocols. Processes can be written in almost
27any language.
28@code{C}, @code{Java} and @code{Guile} APIs exist for accessing existing
29services and for writing extensions.
30It is possible to write extensions in other languages by
31implementing the necessary IPC protocols.
32
33GNUnet can be extended and improved along many possible dimensions, and
34anyone interested in Free Software and Freedom-enhancing Networking is
35welcome to join the effort. This Developer Handbook attempts to provide
36an initial introduction to some of the key design choices and central
37components of the system.
38This part of the GNUnet documentation is far from complete,
39and we welcome informed contributions, be it in the form of
40new chapters, sections or insightful comments.
41
42@menu
43* Developer Introduction::
44* Internal dependencies::
45* Code overview::
46* System Architecture::
47* Subsystem stability::
48* Naming conventions and coding style guide::
49* Build-system::
50* Developing extensions for GNUnet using the gnunet-ext template::
51* Writing testcases::
52* Building GNUnet and its dependencies::
53* TESTING library::
54* Performance regression analysis with Gauger::
55* TESTBED Subsystem::
56* libgnunetutil::
57* Automatic Restart Manager (ARM)::
58* TRANSPORT Subsystem::
59* NAT library::
60* Distance-Vector plugin::
61* SMTP plugin::
62* Bluetooth plugin::
63* WLAN plugin::
64* ATS Subsystem::
65* CORE Subsystem::
66* CADET Subsystem::
67* NSE Subsystem::
68* HOSTLIST Subsystem::
69* IDENTITY Subsystem::
70* NAMESTORE Subsystem::
71* PEERINFO Subsystem::
72* PEERSTORE Subsystem::
73* SET Subsystem::
74* SETI Subsystem::
75* SETU Subsystem::
76* STATISTICS Subsystem::
77* Distributed Hash Table (DHT)::
78* GNU Name System (GNS)::
79* GNS Namecache::
80* REVOCATION Subsystem::
81* File-sharing (FS) Subsystem::
82* REGEX Subsystem::
83* REST Subsystem::
84* RPS Subsystem::
85* TRANSPORT-NG Subsystem::
86* MESSENGER Subsystem::
87@end menu
88
89@node Developer Introduction
90@section Developer Introduction
91
92This Developer Handbook is intended as first introduction to GNUnet for
93new developers that want to extend the GNUnet framework. After the
94introduction, each of the GNUnet subsystems (directories in the
95@file{src/} tree) is (supposed to be) covered in its own chapter. In
96addition to this documentation, GNUnet developers should be aware of the
97services available on the GNUnet server to them.
98
99New developers can have a look a the @uref{https://docs.gnunet.org/tutorial/gnunet-tutorial.html, GNUnet C tutorial}.
100
101@c ** FIXME: Link to files in source, not online.
102@c ** FIXME: Where is the Java tutorial?
103
104In addition to the GNUnet Reference Documentation you are reading,
105the GNUnet server at @uref{https://gnunet.org} contains
106various resources for GNUnet developers and those
107who aspire to become regular contributors.
108They are all conveniently reachable via the "Developer"
109entry in the navigation menu. Some additional tools (such as continuous
110integration) require a special developer access to perform certain
111operations. If you want (or require) access, you should contact
112GNUnet's maintainers.
113
114@c FIXME: A good part of this belongs on the website or should be
115@c extended in subsections explaining usage of this. A simple list
116@c is just taking space people have to read.
117The developer services on the GNUnet project infrastructure are:
118
119@itemize @bullet
120
121@item The version control system (git) keeps our code and enables
122distributed development.
123It is publicly accessible at @uref{https://git.gnunet.org/}.
124Only developers with write access can commit code, everyone else is
125encouraged to submit patches to the GNUnet-developers mailinglist:
126@uref{https://lists.gnu.org/mailman/listinfo/gnunet-developers, https://lists.gnu.org/mailman/listinfo/gnunet-developers}
127
128@item The bugtracking system (Mantis).
129We use it to track feature requests, open bug reports and their
130resolutions.
131It can be accessed at
132@uref{https://bugs.gnunet.org/, https://bugs.gnunet.org/}.
133Anyone can report bugs.
134
135@item Continuous integration (Buildbot).
136Used to build gnunet and its websites upon new commits.
137It can be accessed at
138@uref{https://buildbot.gnunet.org/, https://buildbot.gnunet.org/}.
139Anyone can see the builds.
140
141@item Regularly we make use of static analysis tools.
142Note that not everything that is flagged by the
143analysis is a bug, sometimes even good code can be marked as possibly
144problematic. Nevertheless, developers are encouraged to at least be
145aware of all issues in their code that are listed.
146
147@c @item We use Gauger for automatic performance regression visualization.
148@c FIXME: LINK!
149@c Details on how to use Gauger are here.
150
151@end itemize
152
153
154
155@c ***********************************************************************
156@menu
157* Project overview::
158@end menu
159
160@node Project overview
161@subsection Project overview
162
163The GNUnet project consists at this point of several sub-projects. This
164section is supposed to give an initial overview about the various
165sub-projects. Note that this description also lists projects that are far
166from complete, including even those that have literally not a single line
167of code in them yet.
168
169GNUnet sub-projects in order of likely relevance are currently:
170
171@table @asis
172
173@item @command{gnunet}
174Core of the P2P framework, including file-sharing, VPN and
175chat applications; this is what the Developer Handbook covers mostly
176@item @command{gnunet-gtk}
177Gtk+-based user interfaces, including:
178
179@itemize @bullet
180@item @command{gnunet-fs-gtk} (file-sharing),
181@item @command{gnunet-statistics-gtk} (statistics over time),
182@item @command{gnunet-peerinfo-gtk}
183(information about current connections and known peers),
184@item @command{gnunet-namestore-gtk} (GNS record editor),
185@item @command{gnunet-conversation-gtk} (voice chat GUI) and
186@item @command{gnunet-setup} (setup tool for "everything")
187@end itemize
188
189@item @command{gnunet-fuse}
190Mounting directories shared via GNUnet's file-sharing
191on GNU/Linux distributions
192@item @command{gnunet-update}
193Installation and update tool
194@item @command{gnunet-ext}
195Template for starting 'external' GNUnet projects
196@item @command{gnunet-java}
197Java APIs for writing GNUnet services and applications
198@item @command{gnunet-java-ext}
199@item @command{eclectic}
200Code to run GNUnet nodes on testbeds for research, development,
201testing and evaluation
202@c ** FIXME: Solve the status and location of gnunet-qt
203@item @command{gnunet-qt}
204Qt-based GNUnet GUI (is it deprecated?)
205@item @command{gnunet-cocoa}
206cocoa-based GNUnet GUI (is it deprecated?)
207@item @command{gnunet-guile}
208Guile bindings for GNUnet
209@item @command{gnunet-python}
210Python bindings for GNUnet
211
212@end table
213
214We are also working on various supporting libraries and tools:
215@c ** FIXME: What about gauger, and what about libmwmodem?
216
217@table @asis
218@item @command{libextractor}
219GNU libextractor (meta data extraction)
220@item @command{libmicrohttpd}
221GNU libmicrohttpd (embedded HTTP(S) server library)
222@item @command{gauger}
223Tool for performance regression analysis
224@item @command{monkey}
225Tool for automated debugging of distributed systems
226@item @command{libmwmodem}
227Library for accessing satellite connection quality reports
228@item @command{libgnurl}
229gnURL (feature-restricted variant of cURL/libcurl)
230@item @command{www}
231the gnunet.org website (Jinja2 based)
232@item @command{bibliography}
233Our collected bibliography, papers, references, and so forth
234@item @command{gnunet-videos-}
235Videos about and around GNUnet activities
236@end table
237
238Finally, there are various external projects (see links for a list of
239those that have a public website) which build on top of the GNUnet
240framework.
241
242@c ***********************************************************************
243@node Internal dependencies
244@section Internal dependencies
245
246This section tries to give an overview of what processes a typical GNUnet
247peer running a particular application would consist of. All of the
248processes listed here should be automatically started by
249@command{gnunet-arm -s}.
250The list is given as a rough first guide to users for failure diagnostics.
251Ideally, end-users should never have to worry about these internal
252dependencies.
253
254In terms of internal dependencies, a minimum file-sharing system consists
255of the following GNUnet processes (in order of dependency):
256
257@itemize @bullet
258@item gnunet-service-arm
259@item gnunet-service-resolver (required by all)
260@item gnunet-service-statistics (required by all)
261@item gnunet-service-peerinfo
262@item gnunet-service-transport (requires peerinfo)
263@item gnunet-service-core (requires transport)
264@item gnunet-daemon-hostlist (requires core)
265@item gnunet-daemon-topology (requires hostlist, peerinfo)
266@item gnunet-service-datastore
267@item gnunet-service-dht (requires core)
268@item gnunet-service-identity
269@item gnunet-service-fs (requires identity, mesh, dht, datastore, core)
270@end itemize
271
272@noindent
273A minimum VPN system consists of the following GNUnet processes (in
274order of dependency):
275
276@itemize @bullet
277@item gnunet-service-arm
278@item gnunet-service-resolver (required by all)
279@item gnunet-service-statistics (required by all)
280@item gnunet-service-peerinfo
281@item gnunet-service-transport (requires peerinfo)
282@item gnunet-service-core (requires transport)
283@item gnunet-daemon-hostlist (requires core)
284@item gnunet-service-dht (requires core)
285@item gnunet-service-mesh (requires dht, core)
286@item gnunet-service-dns (requires dht)
287@item gnunet-service-regex (requires dht)
288@item gnunet-service-vpn (requires regex, dns, mesh, dht)
289@end itemize
290
291@noindent
292A minimum GNS system consists of the following GNUnet processes (in
293order of dependency):
294
295@itemize @bullet
296@item gnunet-service-arm
297@item gnunet-service-resolver (required by all)
298@item gnunet-service-statistics (required by all)
299@item gnunet-service-peerinfo
300@item gnunet-service-transport (requires peerinfo)
301@item gnunet-service-core (requires transport)
302@item gnunet-daemon-hostlist (requires core)
303@item gnunet-service-dht (requires core)
304@item gnunet-service-mesh (requires dht, core)
305@item gnunet-service-dns (requires dht)
306@item gnunet-service-regex (requires dht)
307@item gnunet-service-vpn (requires regex, dns, mesh, dht)
308@item gnunet-service-identity
309@item gnunet-service-namestore (requires identity)
310@item gnunet-service-gns (requires vpn, dns, dht, namestore, identity)
311@end itemize
312
313@c ***********************************************************************
314@node Code overview
315@section Code overview
316
317This section gives a brief overview of the GNUnet source code.
318Specifically, we sketch the function of each of the subdirectories in
319the @file{gnunet/src/} directory. The order given is roughly bottom-up
320(in terms of the layers of the system).
321
322@table @asis
323@item @file{util/} --- libgnunetutil
324Library with general utility functions, all
325GNUnet binaries link against this library. Anything from memory
326allocation and data structures to cryptography and inter-process
327communication. The goal is to provide an OS-independent interface and
328more 'secure' or convenient implementations of commonly used primitives.
329The API is spread over more than a dozen headers, developers should study
330those closely to avoid duplicating existing functions.
331@pxref{libgnunetutil}.
332@item @file{hello/} --- libgnunethello
333HELLO messages are used to
334describe under which addresses a peer can be reached (for example,
335protocol, IP, port). This library manages parsing and generating of HELLO
336messages.
337@item @file{block/} --- libgnunetblock
338The DHT and other components of GNUnet
339store information in units called 'blocks'. Each block has a type and the
340type defines a particular format and how that binary format is to be
341linked to a hash code (the key for the DHT and for databases). The block
342library is a wrapper around block plugins which provide the necessary
343functions for each block type.
344@item @file{statistics/} --- statistics service
345The statistics service enables associating
346values (of type uint64_t) with a component name and a string. The main
347uses is debugging (counting events), performance tracking and user
348entertainment (what did my peer do today?).
349@item @file{arm/} --- Automatic Restart Manager (ARM)
350The automatic-restart-manager (ARM) service
351is the GNUnet master service. Its role is to start gnunet-services, to
352re-start them when they crashed and finally to shut down the system when
353requested.
354@item @file{peerinfo/} --- peerinfo service
355The peerinfo service keeps track of which peers are known
356to the local peer and also tracks the validated addresses for each peer
357(in the form of a HELLO message) for each of those peers. The peer is not
358necessarily connected to all peers known to the peerinfo service.
359Peerinfo provides persistent storage for peer identities --- peers are
360not forgotten just because of a system restart.
361@item @file{datacache/} --- libgnunetdatacache
362The datacache library provides (temporary) block storage for the DHT.
363Existing plugins can store blocks in Sqlite, Postgres or MySQL databases.
364All data stored in the cache is lost when the peer is stopped or
365restarted (datacache uses temporary tables).
366@item @file{datastore/} --- datastore service
367The datastore service stores file-sharing blocks in
368databases for extended periods of time. In contrast to the datacache, data
369is not lost when peers restart. However, quota restrictions may still
370cause old, expired or low-priority data to be eventually discarded.
371Existing plugins can store blocks in Sqlite, Postgres or MySQL databases.
372@item @file{template/} --- service template
373Template for writing a new service. Does nothing.
374@item @file{ats/} --- Automatic Transport Selection
375The automatic transport selection (ATS) service
376is responsible for deciding which address (i.e.
377which transport plugin) should be used for communication with other peers,
378and at what bandwidth.
379@item @file{nat/} --- libgnunetnat
380Library that provides basic functions for NAT traversal.
381The library supports NAT traversal with
382manual hole-punching by the user, UPnP and ICMP-based autonomous NAT
383traversal. The library also includes an API for testing if the current
384configuration works and the @code{gnunet-nat-server} which provides an
385external service to test the local configuration.
386@item @file{fragmentation/} --- libgnunetfragmentation
387Some transports (UDP and WLAN, mostly) have restrictions on the maximum
388transfer unit (MTU) for packets. The fragmentation library can be used to
389break larger packets into chunks of at most 1k and transmit the resulting
390fragments reliably (with acknowledgment, retransmission, timeouts,
391etc.).
392@item @file{transport/} --- transport service
393The transport service is responsible for managing the
394basic P2P communication. It uses plugins to support P2P communication
395over TCP, UDP, HTTP, HTTPS and other protocols. The transport service
396validates peer addresses, enforces bandwidth restrictions, limits the
397total number of connections and enforces connectivity restrictions (e.g.
398friends-only).
399@item @file{peerinfo-tool/} --- gnunet-peerinfo
400This directory contains the gnunet-peerinfo binary which can be used to
401inspect the peers and HELLOs known to the peerinfo service.
402@item @file{core/}
403The core service is responsible for establishing encrypted, authenticated
404connections with other peers, encrypting and decrypting messages and
405forwarding messages to higher-level services that are interested in them.
406@item @file{testing/} --- libgnunettesting
407The testing library allows starting (and stopping) peers
408for writing testcases.
409It also supports automatic generation of configurations for peers
410ensuring that the ports and paths are disjoint. libgnunettesting is also
411the foundation for the testbed service
412@item @file{testbed/} --- testbed service
413The testbed service is used for creating small or large scale deployments
414of GNUnet peers for evaluation of protocols.
415It facilitates peer deployments on multiple
416hosts (for example, in a cluster) and establishing various network
417topologies (both underlay and overlay).
418@item @file{nse/} --- Network Size Estimation
419The network size estimation (NSE) service
420implements a protocol for (securely) estimating the current size of the
421P2P network.
422@item @file{dht/} --- distributed hash table
423The distributed hash table (DHT) service provides a
424distributed implementation of a hash table to store blocks under hash
425keys in the P2P network.
426@item @file{hostlist/} --- hostlist service
427The hostlist service allows learning about
428other peers in the network by downloading HELLO messages from an HTTP
429server, can be configured to run such an HTTP server and also implements
430a P2P protocol to advertise and automatically learn about other peers
431that offer a public hostlist server.
432@item @file{topology/} --- topology service
433The topology service is responsible for
434maintaining the mesh topology. It tries to maintain connections to friends
435(depending on the configuration) and also tries to ensure that the peer
436has a decent number of active connections at all times. If necessary, new
437connections are added. All peers should run the topology service,
438otherwise they may end up not being connected to any other peer (unless
439some other service ensures that core establishes the required
440connections). The topology service also tells the transport service which
441connections are permitted (for friend-to-friend networking)
442@item @file{fs/} --- file-sharing
443The file-sharing (FS) service implements GNUnet's
444file-sharing application. Both anonymous file-sharing (using gap) and
445non-anonymous file-sharing (using dht) are supported.
446@item @file{cadet/} --- cadet service
447The CADET service provides a general-purpose routing abstraction to create
448end-to-end encrypted tunnels in mesh networks. We wrote a paper
449documenting key aspects of the design.
450@item @file{tun/} --- libgnunettun
451Library for building IPv4, IPv6 packets and creating
452checksums for UDP, TCP and ICMP packets. The header
453defines C structs for common Internet packet formats and in particular
454structs for interacting with TUN (virtual network) interfaces.
455@item @file{mysql/} --- libgnunetmysql
456Library for creating and executing prepared MySQL
457statements and to manage the connection to the MySQL database.
458Essentially a lightweight wrapper for the interaction between GNUnet
459components and libmysqlclient.
460@item @file{dns/}
461Service that allows intercepting and modifying DNS requests of
462the local machine. Currently used for IPv4-IPv6 protocol translation
463(DNS-ALG) as implemented by "pt/" and for the GNUnet naming system. The
464service can also be configured to offer an exit service for DNS traffic.
465@item @file{vpn/} --- VPN service
466The virtual public network (VPN) service provides a virtual
467tunnel interface (VTUN) for IP routing over GNUnet.
468Needs some other peers to run an "exit" service to work.
469Can be activated using the "gnunet-vpn" tool or integrated with DNS using
470the "pt" daemon.
471@item @file{exit/}
472Daemon to allow traffic from the VPN to exit this
473peer to the Internet or to specific IP-based services of the local peer.
474Currently, an exit service can only be restricted to IPv4 or IPv6, not to
475specific ports and or IP address ranges. If this is not acceptable,
476additional firewall rules must be added manually. exit currently only
477works for normal UDP, TCP and ICMP traffic; DNS queries need to leave the
478system via a DNS service.
479@item @file{pt/}
480protocol translation daemon. This daemon enables 4-to-6,
4816-to-4, 4-over-6 or 6-over-4 transitions for the local system. It
482essentially uses "DNS" to intercept DNS replies and then maps results to
483those offered by the VPN, which then sends them using mesh to some daemon
484offering an appropriate exit service.
485@item @file{identity/}
486Management of egos (alter egos) of a user; identities are
487essentially named ECC private keys and used for zones in the GNU name
488system and for namespaces in file-sharing, but might find other uses later
489@item @file{revocation/}
490Key revocation service, can be used to revoke the
491private key of an identity if it has been compromised
492@item @file{namecache/}
493Cache for resolution results for the GNU name system;
494data is encrypted and can be shared among users,
495loss of the data should ideally only result in a
496performance degradation (persistence not required)
497@item @file{namestore/}
498Database for the GNU name system with per-user private information,
499persistence required
500@item @file{gns/}
501GNU name system, a GNU approach to DNS and PKI.
502@item @file{dv/}
503A plugin for distance-vector (DV)-based routing.
504DV consists of a service and a transport plugin to provide peers
505with the illusion of a direct P2P connection for connections
506that use multiple (typically up to 3) hops in the actual underlay network.
507@item @file{regex/}
508Service for the (distributed) evaluation of regular expressions.
509@item @file{scalarproduct/}
510The scalar product service offers an API to perform a secure multiparty
511computation which calculates a scalar product between two peers
512without exposing the private input vectors of the peers to each other.
513@item @file{consensus/}
514The consensus service will allow a set of peers to agree
515on a set of values via a distributed set union computation.
516@item @file{reclaim/}
517A decentralized personal data sharing service used to realize a decentralized
518identity provider. Supports OpenID Connect. See also @uref{https://reclaim.gnunet.org}.
519@item @file{rest/}
520The rest API allows access to GNUnet services using RESTful interaction.
521The services provide plugins that can exposed by the rest server.
522@c FIXME: Where did this disappear to?
523@c @item @file{experimentation/}
524@c The experimentation daemon coordinates distributed
525@c experimentation to evaluate transport and ATS properties.
526@end table
527
528@c ***********************************************************************
529@node System Architecture
530@section System Architecture
531
532@c FIXME: For those irritated by the textflow, we are missing images here,
533@c in the short term we should add them back, in the long term this should
534@c work without images or have images with alt-text.
535
536GNUnet developers like LEGOs. The blocks are indestructible, can be
537stacked together to construct complex buildings and it is generally easy
538to swap one block for a different one that has the same shape. GNUnet's
539architecture is based on LEGOs:
540
541@image{images/service_lego_block,5in,,picture of a LEGO block stack - 3 APIs upon IPC/network protocol provided by a service}
542
543This chapter documents the GNUnet LEGO system, also known as GNUnet's
544system architecture.
545
546The most common GNUnet component is a service. Services offer an API (or
547several, depending on what you count as "an API") which is implemented as
548a library. The library communicates with the main process of the service
549using a service-specific network protocol. The main process of the service
550typically doesn't fully provide everything that is needed --- it has holes
551to be filled by APIs to other services.
552
553A special kind of component in GNUnet are user interfaces and daemons.
554Like services, they have holes to be filled by APIs of other services.
555Unlike services, daemons do not implement their own network protocol and
556they have no API:
557
558@image{images/daemon_lego_block,5in,,A daemon in GNUnet is a component that does not offer an API for others to build upon}
559
560The GNUnet system provides a range of services, daemons and user
561interfaces, which are then combined into a layered GNUnet instance (also
562known as a peer).
563
564@image{images/service_stack,5in,,A GNUnet peer consists of many layers of services}
565
566Note that while it is generally possible to swap one service for another
567compatible service, there is often only one implementation. However,
568during development we often have a "new" version of a service in parallel
569with an "old" version. While the "new" version is not working, developers
570working on other parts of the service can continue their development by
571simply using the "old" service. Alternative design ideas can also be
572easily investigated by swapping out individual components. This is
573typically achieved by simply changing the name of the "BINARY" in the
574respective configuration section.
575
576Key properties of GNUnet services are that they must be separate
577processes and that they must protect themselves by applying tight error
578checking against the network protocol they implement (thereby achieving a
579certain degree of robustness).
580
581On the other hand, the APIs are implemented to tolerate failures of the
582service, isolating their host process from errors by the service. If the
583service process crashes, other services and daemons around it should not
584also fail, but instead wait for the service process to be restarted by
585ARM.
586
587
588@c ***********************************************************************
589@node Subsystem stability
590@section Subsystem stability
591
592This section documents the current stability of the various GNUnet
593subsystems. Stability here describes the expected degree of compatibility
594with future versions of GNUnet. For each subsystem we distinguish between
595compatibility on the P2P network level (communication protocol between
596peers), the IPC level (communication between the service and the service
597library) and the API level (stability of the API). P2P compatibility is
598relevant in terms of which applications are likely going to be able to
599communicate with future versions of the network. IPC communication is
600relevant for the implementation of language bindings that re-implement the
601IPC messages. Finally, API compatibility is relevant to developers that
602hope to be able to avoid changes to applications build on top of the APIs
603of the framework.
604
605The following table summarizes our current view of the stability of the
606respective protocols or APIs:
607
608@multitable @columnfractions .20 .20 .20 .20
609@headitem Subsystem @tab P2P @tab IPC @tab C API
610@item util @tab n/a @tab n/a @tab stable
611@item arm @tab n/a @tab stable @tab stable
612@item ats @tab n/a @tab unstable @tab testing
613@item block @tab n/a @tab n/a @tab stable
614@item cadet @tab testing @tab testing @tab testing
615@item consensus @tab experimental @tab experimental @tab experimental
616@item core @tab stable @tab stable @tab stable
617@item datacache @tab n/a @tab n/a @tab stable
618@item datastore @tab n/a @tab stable @tab stable
619@item dht @tab stable @tab stable @tab stable
620@item dns @tab stable @tab stable @tab stable
621@item dv @tab testing @tab testing @tab n/a
622@item exit @tab testing @tab n/a @tab n/a
623@item fragmentation @tab stable @tab n/a @tab stable
624@item fs @tab stable @tab stable @tab stable
625@item gns @tab stable @tab stable @tab stable
626@item hello @tab n/a @tab n/a @tab testing
627@item hostlist @tab stable @tab stable @tab n/a
628@item identity @tab stable @tab stable @tab n/a
629@item multicast @tab experimental @tab experimental @tab experimental
630@item mysql @tab stable @tab n/a @tab stable
631@item namestore @tab n/a @tab stable @tab stable
632@item nat @tab n/a @tab n/a @tab stable
633@item nse @tab stable @tab stable @tab stable
634@item peerinfo @tab n/a @tab stable @tab stable
635@item psyc @tab experimental @tab experimental @tab experimental
636@item pt @tab n/a @tab n/a @tab n/a
637@item regex @tab stable @tab stable @tab stable
638@item revocation @tab stable @tab stable @tab stable
639@item social @tab experimental @tab experimental @tab experimental
640@item statistics @tab n/a @tab stable @tab stable
641@item testbed @tab n/a @tab testing @tab testing
642@item testing @tab n/a @tab n/a @tab testing
643@item topology @tab n/a @tab n/a @tab n/a
644@item transport @tab experimental @tab experimental @tab experimental
645@item tun @tab n/a @tab n/a @tab stable
646@item vpn @tab testing @tab n/a @tab n/a
647@end multitable
648
649Here is a rough explanation of the values:
650
651@table @samp
652@item stable
653No incompatible changes are planned at this time; for IPC/APIs, if
654there are incompatible changes, they will be minor and might only require
655minimal changes to existing code; for P2P, changes will be avoided if at
656all possible for the 0.10.x-series
657
658@item testing
659No incompatible changes are
660planned at this time, but the code is still known to be in flux; so while
661we have no concrete plans, our expectation is that there will still be
662minor modifications; for P2P, changes will likely be extensions that
663should not break existing code
664
665@item unstable
666Changes are planned and will happen; however, they
667will not be totally radical and the result should still resemble what is
668there now; nevertheless, anticipated changes will break protocol/API
669compatibility
670
671@item experimental
672Changes are planned and the result may look nothing like
673what the API/protocol looks like today
674
675@item unknown
676Someone should think about where this subsystem headed
677
678@item n/a
679This subsystem does not have an API/IPC-protocol/P2P-protocol
680@end table
681
682@c ***********************************************************************
683@node Naming conventions and coding style guide
684@section Naming conventions and coding style guide
685
686Here you can find some rules to help you write code for GNUnet.
687
688@c ***********************************************************************
689@menu
690* Naming conventions::
691* Coding style::
692* Continuous integration::
693* Commit messages and developer branches::
694@end menu
695
696@node Naming conventions
697@subsection Naming conventions
698
699
700@c ***********************************************************************
701@menu
702* include files::
703* binaries::
704* logging::
705* configuration::
706* exported symbols::
707* private (library-internal) symbols (including structs and macros)::
708* testcases::
709* performance tests::
710* src/ directories::
711@end menu
712
713@node include files
714@subsubsection include files
715
716@itemize @bullet
717@item _lib: library without need for a process
718@item _service: library that needs a service process
719@item _plugin: plugin definition
720@item _protocol: structs used in network protocol
721@item exceptions:
722@itemize @bullet
723@item gnunet_config.h --- generated
724@item platform.h --- first included
725@item gnunet_common.h --- fundamental routines
726@item gnunet_directories.h --- generated
727@item gettext.h --- external library
728@end itemize
729@end itemize
730
731@c ***********************************************************************
732@node binaries
733@subsubsection binaries
734
735@itemize @bullet
736@item gnunet-service-xxx: service process (has listen socket)
737@item gnunet-daemon-xxx: daemon process (no listen socket)
738@item gnunet-helper-xxx[-yyy]: SUID helper for module xxx
739@item gnunet-yyy: command-line tool for end-users
740@item libgnunet_plugin_xxx_yyy.so: plugin for API xxx
741@item libgnunetxxx.so: library for API xxx
742@end itemize
743
744@c ***********************************************************************
745@node logging
746@subsubsection logging
747
748@itemize @bullet
749@item services and daemons use their directory name in
750@code{GNUNET_log_setup} (e.g. 'core') and log using
751plain 'GNUNET_log'.
752@item command-line tools use their full name in
753@code{GNUNET_log_setup} (e.g. 'gnunet-publish') and log using
754plain 'GNUNET_log'.
755@item service access libraries log using
756'@code{GNUNET_log_from}' and use '@code{DIRNAME-api}' for the
757component (e.g. 'core-api')
758@item pure libraries (without associated service) use
759'@code{GNUNET_log_from}' with the component set to their
760library name (without lib or '@file{.so}'),
761which should also be their directory name (e.g. '@file{nat}')
762@item plugins should use '@code{GNUNET_log_from}'
763with the directory name and the plugin name combined to produce
764the component name (e.g. 'transport-tcp').
765@item logging should be unified per-file by defining a
766@code{LOG} macro with the appropriate arguments,
767along these lines:
768
769@example
770#define LOG(kind,...)
771GNUNET_log_from (kind, "example-api",__VA_ARGS__)
772@end example
773
774@end itemize
775
776@c ***********************************************************************
777@node configuration
778@subsubsection configuration
779
780@itemize @bullet
781@item paths (that are substituted in all filenames) are in PATHS
782(have as few as possible)
783@item all options for a particular module (@file{src/MODULE})
784are under @code{[MODULE]}
785@item options for a plugin of a module
786are under @code{[MODULE-PLUGINNAME]}
787@end itemize
788
789@c ***********************************************************************
790@node exported symbols
791@subsubsection exported symbols
792
793@itemize @bullet
794@item must start with @code{GNUNET_modulename_} and be defined in
795@file{modulename.c}
796@item exceptions: those defined in @file{gnunet_common.h}
797@end itemize
798
799@c ***********************************************************************
800@node private (library-internal) symbols (including structs and macros)
801@subsubsection private (library-internal) symbols (including structs and macros)
802
803@itemize @bullet
804@item must NOT start with any prefix
805@item must not be exported in a way that linkers could use them or@ other
806libraries might see them via headers; they must be either
807declared/defined in C source files or in headers that are in the
808respective directory under @file{src/modulename/} and NEVER be declared
809in @file{src/include/}.
810@end itemize
811
812@node testcases
813@subsubsection testcases
814
815@itemize @bullet
816@item must be called @file{test_module-under-test_case-description.c}
817@item "case-description" maybe omitted if there is only one test
818@end itemize
819
820@c ***********************************************************************
821@node performance tests
822@subsubsection performance tests
823
824@itemize @bullet
825@item must be called @file{perf_module-under-test_case-description.c}
826@item "case-description" maybe omitted if there is only one performance
827test
828@item Must only be run if @code{HAVE_BENCHMARKS} is satisfied
829@end itemize
830
831@c ***********************************************************************
832@node src/ directories
833@subsubsection src/ directories
834
835@itemize @bullet
836@item gnunet-NAME: end-user applications (like gnunet-search or gnunet-arm)
837@item gnunet-service-NAME: service processes with accessor library (e.g.
838gnunet-service-arm)
839@item libgnunetNAME: accessor library (_service.h-header) or standalone
840library (_lib.h-header)
841@item gnunet-daemon-NAME: daemon process without accessor library (e.g.
842gnunet-daemon-hostlist) and no GNUnet management port
843@item libgnunet_plugin_DIR_NAME: loadable plugins (e.g.
844libgnunet_plugin_transport_tcp)
845@end itemize
846
847@cindex Coding style
848@node Coding style
849@subsection Coding style
850
851@c XXX: Adjust examples to GNU Standards!
852@itemize @bullet
853@item We follow the GNU Coding Standards (@pxref{Top, The GNU Coding Standards,, standards, The GNU Coding Standards});
854@item Indentation is done with spaces, two per level, no tabs; specific (incomplete!) indentation rules are provided in an @code{uncrustify} configuration file (in ``contrib/``) and enforced by Git hooks;
855@item C99 struct initialization is fine and generally encouraged (but not required);
856@item As in all good C code, we care about symbol space pollution and thus use @code{static} to limit the scope where possible, even in the compilation unit that contains @code{main};
857@item declare only one variable per line, for example:
858
859@noindent
860instead of
861
862@example
863int i,j;
864@end example
865
866@noindent
867write:
868
869@example
870int i;
871int j;
872@end example
873
874@c TODO: include actual example from a file in source
875
876@noindent
877This helps keep diffs small and forces developers to think precisely about
878the type of every variable.
879Note that @code{char *} is different from @code{const char*} and
880@code{int} is different from @code{unsigned int} or @code{uint32_t}.
881Each variable type should be chosen with care.
882
883@item While @code{goto} should generally be avoided, having a
884@code{goto} to the end of a function to a block of clean up
885statements (free, close, etc.) can be acceptable.
886
887@item Conditions should be written with constants on the left (to avoid
888accidental assignment) and with the @code{true} target being either the
889@code{error} case or the significantly simpler continuation. For example:
890
891@example
892if (0 != stat ("filename,"
893 &sbuf))
894@{
895 error();
896@}
897else
898@{
899 /* handle normal case here */
900@}
901@end example
902
903@noindent
904instead of
905
906@example
907if (stat ("filename," &sbuf) == 0) @{
908 /* handle normal case here */
909 @} else @{
910 error();
911 @}
912@end example
913
914@noindent
915If possible, the error clause should be terminated with a @code{return} (or
916@code{goto} to some cleanup routine) and in this case, the @code{else} clause
917should be omitted:
918
919@example
920if (0 != stat ("filename",
921 &sbuf))
922@{
923 error();
924 return;
925@}
926/* handle normal case here */
927@end example
928
929This serves to avoid deep nesting. The 'constants on the left' rule
930applies to all constants (including. @code{GNUNET_SCHEDULER_NO_TASK}),
931NULL, and enums). With the two above rules (constants on left, errors in
932'true' branch), there is only one way to write most branches correctly.
933
934@item Combined assignments and tests are allowed if they do not hinder
935code clarity. For example, one can write:
936
937@example
938if (NULL == (value = lookup_function()))
939@{
940 error();
941 return;
942@}
943@end example
944
945@item Use @code{break} and @code{continue} wherever possible to avoid
946deep(er) nesting. Thus, we would write:
947
948@example
949next = head;
950while (NULL != (pos = next))
951@{
952 next = pos->next;
953 if (! should_free (pos))
954 continue;
955 GNUNET_CONTAINER_DLL_remove (head,
956 tail,
957 pos);
958 GNUNET_free (pos);
959@}
960@end example
961
962instead of
963
964@example
965next = head; while (NULL != (pos = next)) @{
966 next = pos->next;
967 if (should_free (pos)) @{
968 /* unnecessary nesting! */
969 GNUNET_CONTAINER_DLL_remove (head, tail, pos);
970 GNUNET_free (pos);
971 @}
972 @}
973@end example
974
975@item We primarily use @code{for} and @code{while} loops.
976A @code{while} loop is used if the method for advancing in the loop is
977not a straightforward increment operation. In particular, we use:
978
979@example
980next = head;
981while (NULL != (pos = next))
982@{
983 next = pos->next;
984 if (! should_free (pos))
985 continue;
986 GNUNET_CONTAINER_DLL_remove (head,
987 tail,
988 pos);
989 GNUNET_free (pos);
990@}
991@end example
992
993to free entries in a list (as the iteration changes the structure of the
994list due to the free; the equivalent @code{for} loop does no longer
995follow the simple @code{for} paradigm of @code{for(INIT;TEST;INC)}).
996However, for loops that do follow the simple @code{for} paradigm we do
997use @code{for}, even if it involves linked lists:
998
999@example
1000/* simple iteration over a linked list */
1001for (pos = head;
1002 NULL != pos;
1003 pos = pos->next)
1004@{
1005 use (pos);
1006@}
1007@end example
1008
1009
1010@item The first argument to all higher-order functions in GNUnet must be
1011declared to be of type @code{void *} and is reserved for a closure. We do
1012not use inner functions, as trampolines would conflict with setups that
1013use non-executable stacks.
1014The first statement in a higher-order function, which unusually should
1015be part of the variable declarations, should assign the
1016@code{cls} argument to the precise expected type. For example:
1017
1018@example
1019int
1020callback (void *cls,
1021 char *args)
1022@{
1023 struct Foo *foo = cls;
1024 int other_variables;
1025
1026 /* rest of function */
1027@}
1028@end example
1029
1030@item As shown in the example above, after the return type of a
1031function there should be a break. Each parameter should
1032be on a new line.
1033
1034@item It is good practice to write complex @code{if} expressions instead
1035of using deeply nested @code{if} statements. However, except for addition
1036and multiplication, all operators should use parens. This is fine:
1037
1038@example
1039if ( (1 == foo) ||
1040 ( (0 == bar) &&
1041 (x != y) ) )
1042 return x;
1043@end example
1044
1045
1046However, this is not:
1047
1048@example
1049if (1 == foo)
1050 return x;
1051if (0 == bar && x != y)
1052 return x;
1053@end example
1054
1055@noindent
1056Note that splitting the @code{if} statement above is debatable as the
1057@code{return x} is a very trivial statement. However, once the logic after
1058the branch becomes more complicated (and is still identical), the "or"
1059formulation should be used for sure.
1060
1061@item There should be two empty lines between the end of the function and
1062the comments describing the following function. There should be a single
1063empty line after the initial variable declarations of a function. If a
1064function has no local variables, there should be no initial empty line. If
1065a long function consists of several complex steps, those steps might be
1066separated by an empty line (possibly followed by a comment describing the
1067following step). The code should not contain empty lines in arbitrary
1068places; if in doubt, it is likely better to NOT have an empty line (this
1069way, more code will fit on the screen).
1070
1071
1072@item When command-line arguments become too long (and would result in
1073some particularly ugly @code{uncrustify} wrapping), we start all arguments
1074on a new line. As a result, there must never be a new line within an
1075argument declaration (i.e. between @code{struct} and the struct's name) or
1076between the type and the variable). Example:
1077
1078@example
1079struct GNUNET_TRANSPORT_CommunicatorHandle *
1080GNUNET_TRANSPORT_communicator_connect (
1081 const struct GNUNET_CONFIGURATION_Handle *cfg,
1082 const char *config_section_name,
1083 const char *addr_prefix,
1084 ...);
1085@end example
1086
1087Note that for short function names and arguments, the first argument
1088does remain on the same line. Example:
1089
1090@example
1091void
1092fun (short i,
1093 short j);
1094@end example
1095
1096@end itemize
1097
1098@cindex Continuous integration
1099@node Continuous integration
1100@subsection Continuous integration
1101
1102The continuous integration buildbot can be found at @uref{https://buildbot.gnunet.org}.
1103Repositories need to be enabled by a buildbot admin in order to participate
1104in the builds.
1105
1106The buildbot can be configured to process scripts in your repository root under @code{.buildbot/}:
1107
1108The files @code{build.sh}, @code{install.sh} and @code{test.sh} are executed
1109in order if present. If you want a specific worker to behave differently,
1110you can provide a worker specific script, e.g. @code{myworker_build.sh}.
1111In this case, the generic step will not be executed.
1112
1113For the @code{gnunet.git} repository, you may use "!tarball" or "!coverity" in
1114your commit messages.
1115"!tarball" will trigger a @code{make dist} of the gnunet source and verify that it
1116can be compiled. The artifact will then be published to @uref{https://buildbot.gnunet.org/artifacts}.
1117This is a good way to create a tarball for a release as it verifies the build
1118on another machine.
1119
1120The "!coverity" trigger will trigger a coverity build and submit the results
1121for analysis to coverity: @uref{https://scan.coverity.com/}.
1122Only developers with accounts for the GNUnet project on coverity.com are able to
1123see the analysis results.
1124
1125@cindex Commit messages and developer branches
1126@node Commit messages and developer branches
1127@subsection Commit messages and developer branches
1128
1129You can find the GNUnet project repositories at @uref{https://git.gnunet.org}.
1130For each release, the ChangeLog file is generated from the commit history.
1131Hence, commit messages are required to convey what changes were made in
1132a self-contained fashion. Commit messages such as "fix" or "cleanup" are
1133not acceptable.
1134You commit message should ideally start with the subsystem name and be followed
1135by a succinct description of the change. Where applicable a reference to
1136a bug number in the bugtracker may also be included.
1137Example:
1138
1139@example
1140# <subsystem>: <description>. (#XXXX)
1141IDENTITY: Fix wrong key construction for anonymous ECDSA identity. (Fixes #12344)
1142@end example
1143
1144If you need to commit a minor fix you may prefix the commit message with a
1145dash. It will then be ignored when generating the ChangeLog entries:
1146
1147@example
1148# -<text>
1149-fix
1150@end example
1151
1152If you need to modify a commit you can do so using:
1153
1154@example
1155$ git commit --amend
1156@end example
1157
1158If you need to modify a number of successive commits you will have to rebase
1159and squash.
1160Note that most branches are protected. This means that you can only fix commits
1161as long as they are not pushed. You can only modify pushed commits in your own
1162developer branches.
1163
1164A developer branch is a branch which matches a developer-specific prefix.
1165As a developer with git access, you should have a git username. If you do not
1166know it, please ask an admin.
1167A developer branch has the format:
1168
1169@example
1170dev/<username>/<branchname>
1171@end example
1172
1173
1174Assuming the developer with username "jdoe" wants to create a new branch for an
1175i18n fix, the branch name could be:
1176
1177@example
1178dev/jdoe/i18n_fx
1179@end example
1180
1181The developer will be able to force push to and delete branches under his prefix.
1182It is highly recommended to work in your own developer branches.
1183Code which conforms to the commit message guidelines and coding style, is tested
1184and builds may be merged to the master branch.
1185Preferably, you would then...
1186
1187@itemize
1188@item ...squash your commits,
1189@item rebase to master and then
1190@item merge your branch.
1191@item (optional) Delete the branch.
1192@end itemize
1193
1194In general, you may want to follow the rule "commit often, push tidy":
1195You can create smaller, succinct commits with limited meaning on the commit
1196messages. In the end and before you push or merge your branch, you
1197can then squash the commits or rename them.
1198
1199@c ***********************************************************************
1200@node Build-system
1201@section Build-system
1202
1203If you have code that is likely not to compile or build rules you might
1204want to not trigger for most developers, use @code{if HAVE_EXPERIMENTAL}
1205in your @file{Makefile.am}.
1206Then it is OK to (temporarily) add non-compiling (or known-to-not-port)
1207code.
1208
1209If you want to compile all testcases but NOT run them, run configure with
1210the @code{--enable-test-suppression} option.
1211
1212If you want to run all testcases, including those that take a while, run
1213configure with the @code{--enable-expensive-testcases} option.
1214
1215If you want to compile and run benchmarks, run configure with the
1216@code{--enable-benchmarks} option.
1217
1218If you want to obtain code coverage results, run configure with the
1219@code{--enable-coverage} option and run the @file{coverage.sh} script in
1220the @file{contrib/} directory.
1221
1222@cindex gnunet-ext
1223@node Developing extensions for GNUnet using the gnunet-ext template
1224@section Developing extensions for GNUnet using the gnunet-ext template
1225
1226For developers who want to write extensions for GNUnet we provide the
1227gnunet-ext template to provide an easy to use skeleton.
1228
1229gnunet-ext contains the build environment and template files for the
1230development of GNUnet services, command line tools, APIs and tests.
1231
1232First of all you have to obtain gnunet-ext from git:
1233
1234@example
1235git clone https://git.gnunet.org/gnunet-ext.git
1236@end example
1237
1238The next step is to bootstrap and configure it. For configure you have to
1239provide the path containing GNUnet with
1240@code{--with-gnunet=/path/to/gnunet} and the prefix where you want the
1241install the extension using @code{--prefix=/path/to/install}:
1242
1243@example
1244./bootstrap
1245./configure --prefix=/path/to/install --with-gnunet=/path/to/gnunet
1246@end example
1247
1248When your GNUnet installation is not included in the default linker search
1249path, you have to add @code{/path/to/gnunet} to the file
1250@file{/etc/ld.so.conf} and run @code{ldconfig} or your add it to the
1251environmental variable @code{LD_LIBRARY_PATH} by using
1252
1253@example
1254export LD_LIBRARY_PATH=/path/to/gnunet/lib
1255@end example
1256
1257@cindex writing testcases
1258@node Writing testcases
1259@section Writing testcases
1260
1261Ideally, any non-trivial GNUnet code should be covered by automated
1262testcases. Testcases should reside in the same place as the code that is
1263being tested. The name of source files implementing tests should begin
1264with @code{test_} followed by the name of the file that contains
1265the code that is being tested.
1266
1267Testcases in GNUnet should be integrated with the autotools build system.
1268This way, developers and anyone building binary packages will be able to
1269run all testcases simply by running @code{make check}. The final
1270testcases shipped with the distribution should output at most some brief
1271progress information and not display debug messages by default. The
1272success or failure of a testcase must be indicated by returning zero
1273(success) or non-zero (failure) from the main method of the testcase.
1274The integration with the autotools is relatively straightforward and only
1275requires modifications to the @file{Makefile.am} in the directory
1276containing the testcase. For a testcase testing the code in @file{foo.c}
1277the @file{Makefile.am} would contain the following lines:
1278
1279@example
1280check_PROGRAMS = test_foo
1281TESTS = $(check_PROGRAMS)
1282test_foo_SOURCES = test_foo.c
1283test_foo_LDADD = $(top_builddir)/src/util/libgnunetutil.la
1284@end example
1285
1286Naturally, other libraries used by the testcase may be specified in the
1287@code{LDADD} directive as necessary.
1288
1289Often testcases depend on additional input files, such as a configuration
1290file. These support files have to be listed using the @code{EXTRA_DIST}
1291directive in order to ensure that they are included in the distribution.
1292
1293Example:
1294
1295@example
1296EXTRA_DIST = test_foo_data.conf
1297@end example
1298
1299Executing @code{make check} will run all testcases in the current
1300directory and all subdirectories. Testcases can be compiled individually
1301by running @code{make test_foo} and then invoked directly using
1302@code{./test_foo}. Note that due to the use of plugins in GNUnet, it is
1303typically necessary to run @code{make install} before running any
1304testcases. Thus the canonical command @code{make check install} has to be
1305changed to @code{make install check} for GNUnet.
1306
1307@c ***********************************************************************
1308@cindex Building GNUnet
1309@node Building GNUnet and its dependencies
1310@section Building GNUnet and its dependencies
1311
1312In the following section we will outline how to build GNUnet and
1313some of its dependencies. We will assume a fair amount of knowledge
1314for building applications under UNIX-like systems. Furthermore we
1315assume that the build environment is sane and that you are aware of
1316any implications actions in this process could have.
1317Instructions here can be seen as notes for developers (an extension to
1318the 'HACKING' section in README) as well as package maintainers.
1319@b{Users should rely on the available binary packages.}
1320We will use Debian as an example Operating System environment. Substitute
1321accordingly with your own Operating System environment.
1322
1323For the full list of dependencies, consult the appropriate, up-to-date
1324section in the @file{README} file.
1325
1326@example
1327libgpgerror, libgcrypt, libnettle, libunbound, GnuTLS (with libunbound
1328support)
1329@end example
1330
1331After we have build and installed those packages, we continue with
1332packages closer to GNUnet in this step: libgnurl (our libcurl fork),
1333GNU libmicrohttpd, and GNU libextractor. Again, if your package manager
1334provides one of these packages, use the packages provided from it
1335unless you have good reasons (package version too old, conflicts, etc).
1336We advise against compiling widely used packages such as GnuTLS
1337yourself if your OS provides a variant already unless you take care
1338of maintenance of the packages then.
1339
1340In the optimistic case, this command will give you all the dependencies
1341on Debian, Debian derived systems or any Linux Operating System using
1342the apt package manager:
1343
1344@example
1345sudo apt-get install libgnurl libmicrohttpd libextractor
1346@end example
1347
1348From experience we know that at the very least libgnurl is not
1349available in some environments. You could substitute libgnurl
1350with libcurl, but we recommend to install libgnurl, as it gives
1351you a predefined libcurl with the small set GNUnet requires.
1352libgnurl has been developed to co-exist with libcurl installations,
1353installing it will cause no filename or namespace collisions.
1354
1355@cindex libgnurl
1356@cindex compiling libgnurl
1357GNUnet and some of its function depend on a limited subset of cURL/libcurl.
1358Rather than trying to enforce a certain configuration on the world, we
1359opted to maintain a microfork of it that ensures that we can link
1360against the right set of features.
1361We called this specialized set of libcurl "libgnurl".
1362It is fully ABI compatible with libcurl and currently used by
1363GNUnet and some of its dependencies.
1364
1365We download libgnurl and its digital signature from the GNU fileserver,
1366assuming @env{TMPDIR} exists.
1367
1368@quotation
1369Note: TMPDIR might be @file{/tmp}, @env{TMPDIR}, @env{TMP} or any other
1370location. For consistency we assume @env{TMPDIR} points to @file{/tmp}
1371for the remainder of this section.
1372@end quotation
1373
1374@example
1375cd \$TMPDIR
1376wget https://ftp.gnu.org/gnu/gnunet/gnurl-7.65.3.tar.Z
1377wget https://ftp.gnu.org/gnu/gnunet/gnurl-7.65.3.tar.Z.sig
1378@end example
1379
1380Next, verify the digital signature of the file:
1381
1382@example
1383gpg --verify gnurl-7.65.3.tar.Z.sig
1384@end example
1385
1386If gpg fails, you might try with @command{gpg2} on your OS. If the error
1387states that ``the key can not be found'' or it is unknown, you have to
1388retrieve the key (A88C8ADD129828D7EAC02E52E22F9BBFEE348588) from a
1389keyserver first:
1390
1391@example
1392gpg --keyserver pgp.mit.edu --recv-keys A88C8ADD129828D7EAC02E52E22F9BBFEE348588
1393@end example
1394
1395or
1396
1397@example
1398gpg --keyserver hkps://keys.openpgp.org --recv-keys A88C8ADD129828D7EAC02E52E22F9BBFEE348588
1399@end example
1400
1401and rerun the verification command.
1402
1403libgnurl will require the following packages to be present at runtime:
1404GnuTLS (with DANE support / libunbound), libidn, zlib and at compile time:
1405libtool, perl, pkg-config, and (for tests) python (2.7, or
1406any version of python 3).
1407
1408Once you have verified that all the required packages are present on your
1409system, we can proceed to compile libgnurl. This assumes you will install
1410gnurl in the default location as prefix. To change this, pass --prefix= to
1411the configure-gnurl script (which is a simple wrapper around configure).
1412
1413@example
1414tar -xvf gnurl-7.65.3.tar.Z
1415cd gnurl-7.65.3
1416sh ./configure-gnurl
1417make
1418make -C tests test
1419sudo make install
1420@end example
1421
1422After you've compiled and installed libgnurl, we can proceed to building
1423GNUnet.
1424
1425
1426
1427
1428First, in addition to the GNUnet sources you might require downloading the
1429latest version of various dependencies, depending on how recent the
1430software versions in your distribution of GNU/Linux are.
1431Most distributions do not include sufficiently recent versions of these
1432dependencies.
1433Thus, a typically installation on a "modern" GNU/Linux distribution
1434requires you to install the following dependencies (ideally in this
1435order):
1436
1437@itemize @bullet
1438@item libgpgerror and libgcrypt
1439@item libnettle and libunbound (possibly from distribution), GnuTLS
1440@item libgnurl (read the README)
1441@item GNU libmicrohttpd
1442@item GNU libextractor
1443@end itemize
1444
1445Make sure to first install the various mandatory and optional
1446dependencies including development headers from your distribution.
1447
1448Other dependencies that you should strongly consider to install is a
1449database (MySQL, SQLite3 or Postgres).
1450The following instructions will assume that you installed at least
1451SQLite3 (commonly distributed as ``sqlite'' or ``sqlite3'').
1452For most distributions you should be able to find pre-build packages for
1453the database. Again, make sure to install the client libraries @b{and} the
1454respective development headers (if they are packaged separately) as well.
1455
1456@c TODO: Do these platform specific descriptions still exist? If not,
1457@c we should find a way to sync website parts with this texinfo.
1458You can find specific, detailed instructions for installing of the
1459dependencies (and possibly the rest of the GNUnet installation) in the
1460platform-specific descriptions, which can be found in the Index.
1461Please consult them now.
1462If your distribution is not listed, please study the build
1463instructions for Debian stable, carefully as you try to install the
1464dependencies for your own distribution.
1465Contributing additional instructions for further platforms is always
1466appreciated.
1467Please take in mind that operating system development tends to move at
1468a rather fast speed. Due to this you should be aware that some of
1469the instructions could be outdated by the time you are reading this.
1470If you find a mistake, please tell us about it (or even better: send
1471a patch to the documentation to fix it!).
1472
1473Before proceeding further, please double-check the dependency list.
1474Note that in addition to satisfying the dependencies, you might have to
1475make sure that development headers for the various libraries are also
1476installed.
1477There maybe files for other distributions, or you might be able to find
1478equivalent packages for your distribution.
1479
1480While it is possible to build and install GNUnet without having root
1481access, we will assume that you have full control over your system in
1482these instructions.
1483First, you should create a system user @emph{gnunet} and an additional
1484group @emph{gnunetdns}. On the GNU/Linux distributions Debian and Ubuntu,
1485type:
1486
1487@example
1488sudo adduser --system --home /var/lib/gnunet --group \
1489--disabled-password gnunet
1490sudo addgroup --system gnunetdns
1491@end example
1492
1493@noindent
1494On other Unix-like systems, this should have the same effect:
1495
1496@example
1497sudo useradd --system --groups gnunet --home-dir /var/lib/gnunet
1498sudo addgroup --system gnunetdns
1499@end example
1500
1501Now compile and install GNUnet using:
1502
1503@example
1504tar xvf gnunet-@value{VERSION}.tar.gz
1505cd gnunet-@value{VERSION}
1506./configure --with-sudo=sudo --with-nssdir=/lib
1507make
1508sudo make install
1509@end example
1510
1511If you want to be able to enable DEBUG-level log messages, add
1512@code{--enable-logging=verbose} to the end of the
1513@command{./configure} command.
1514@code{DEBUG}-level log messages are in English only and
1515should only be useful for developers (or for filing
1516really detailed bug reports).
1517
1518@noindent
1519Next, edit the file @file{/etc/gnunet.conf} to contain the following:
1520
1521@example
1522[arm]
1523START_SYSTEM_SERVICES = YES
1524START_USER_SERVICES = NO
1525@end example
1526
1527@noindent
1528You may need to update your @code{ld.so} cache to include
1529files installed in @file{/usr/local/lib}:
1530
1531@example
1532# ldconfig
1533@end example
1534
1535@noindent
1536Then, switch from user @code{root} to user @code{gnunet} to start
1537the peer:
1538
1539@example
1540# su -s /bin/sh - gnunet
1541$ gnunet-arm -c /etc/gnunet.conf -s
1542@end example
1543
1544You may also want to add the last line in the gnunet user's @file{crontab}
1545prefixed with @code{@@reboot} so that it is executed whenever the system
1546is booted:
1547
1548@example
1549@@reboot /usr/local/bin/gnunet-arm -c /etc/gnunet.conf -s
1550@end example
1551
1552@noindent
1553This will only start the system-wide GNUnet services.
1554Type @command{exit} to get back your root shell.
1555Now, you need to configure the per-user part. For each
1556user that should get access to GNUnet on the system, run
1557(replace alice with your username):
1558
1559@example
1560sudo adduser alice gnunet
1561@end example
1562
1563@noindent
1564to allow them to access the system-wide GNUnet services. Then, each
1565user should create a configuration file @file{~/.config/gnunet.conf}
1566with the lines:
1567
1568@example
1569[arm]
1570START_SYSTEM_SERVICES = NO
1571START_USER_SERVICES = YES
1572DEFAULTSERVICES = gns
1573@end example
1574
1575@noindent
1576and start the per-user services using
1577
1578@example
1579$ gnunet-arm -c ~/.config/gnunet.conf -s
1580@end example
1581
1582@noindent
1583Again, adding a @code{crontab} entry to autostart the peer is advised:
1584
1585@example
1586@@reboot /usr/local/bin/gnunet-arm -c $HOME/.config/gnunet.conf -s
1587@end example
1588
1589@noindent
1590Note that some GNUnet services (such as socks5 proxies) may need a
1591system-wide TCP port for each user.
1592For those services, systems with more than one user may require each user
1593to specify a different port number in their personal configuration file.
1594
1595Finally, the user should perform the basic initial setup for the GNU Name
1596System (GNS) certificate authority. This is done by running:
1597
1598@example
1599$ gnunet-gns-proxy-setup-ca
1600@end example
1601
1602@noindent
1603The first generates the default zones, whereas the second setups the GNS
1604Certificate Authority with the user's browser. Now, to activate GNS in the
1605normal DNS resolution process, you need to edit your
1606@file{/etc/nsswitch.conf} where you should find a line like this:
1607
1608@example
1609hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4
1610@end example
1611
1612@noindent
1613The exact details may differ a bit, which is fine. Add the text
1614@emph{"gns [NOTFOUND=return]"} after @emph{"files"}.
1615Keep in mind that we included a backslash ("\") here just for
1616markup reasons. You should write the text below on @b{one line}
1617and @b{without} the "\":
1618
1619@example
1620hosts: files gns [NOTFOUND=return] mdns4_minimal \
1621[NOTFOUND=return] dns mdns4
1622@end example
1623
1624@c FIXME: Document new behavior.
1625You might want to make sure that @file{/lib/libnss_gns.so.2} exists on
1626your system, it should have been created during the installation.
1627
1628
1629@c **********************************************************************
1630@cindex TESTING library
1631@node TESTING library
1632@section TESTING library
1633
1634The TESTING library is used for writing testcases which involve starting a
1635single or multiple peers. While peers can also be started by testcases
1636using the ARM subsystem, using TESTING library provides an elegant way to
1637do this. The configurations of the peers are auto-generated from a given
1638template to have non-conflicting port numbers ensuring that peers'
1639services do not run into bind errors. This is achieved by testing ports'
1640availability by binding a listening socket to them before allocating them
1641to services in the generated configurations.
1642
1643An another advantage while using TESTING is that it shortens the testcase
1644startup time as the hostkeys for peers are copied from a pre-computed set
1645of hostkeys instead of generating them at peer startup which may take a
1646considerable amount of time when starting multiple peers or on an embedded
1647processor.
1648
1649TESTING also allows for certain services to be shared among peers. This
1650feature is invaluable when testing with multiple peers as it helps to
1651reduce the number of services run per each peer and hence the total
1652number of processes run per testcase.
1653
1654TESTING library only handles creating, starting and stopping peers.
1655Features useful for testcases such as connecting peers in a topology are
1656not available in TESTING but are available in the TESTBED subsystem.
1657Furthermore, TESTING only creates peers on the localhost, however by
1658using TESTBED testcases can benefit from creating peers across multiple
1659hosts.
1660
1661@menu
1662* API::
1663* Finer control over peer stop::
1664* Helper functions::
1665* Testing with multiple processes::
1666@end menu
1667
1668@cindex TESTING API
1669@node API
1670@subsection API
1671
1672TESTING abstracts a group of peers as a TESTING system. All peers in a
1673system have common hostname and no two services of these peers have a
1674same port or a UNIX domain socket path.
1675
1676TESTING system can be created with the function
1677@code{GNUNET_TESTING_system_create()} which returns a handle to the
1678system. This function takes a directory path which is used for generating
1679the configurations of peers, an IP address from which connections to the
1680peers' services should be allowed, the hostname to be used in peers'
1681configuration, and an array of shared service specifications of type
1682@code{struct GNUNET_TESTING_SharedService}.
1683
1684The shared service specification must specify the name of the service to
1685share, the configuration pertaining to that shared service and the
1686maximum number of peers that are allowed to share a single instance of
1687the shared service.
1688
1689TESTING system created with @code{GNUNET_TESTING_system_create()} chooses
1690ports from the default range @code{12000} - @code{56000} while
1691auto-generating configurations for peers.
1692This range can be customised with the function
1693@code{GNUNET_TESTING_system_create_with_portrange()}. This function is
1694similar to @code{GNUNET_TESTING_system_create()} except that it take 2
1695additional parameters --- the start and end of the port range to use.
1696
1697A TESTING system is destroyed with the function
1698@code{GNUNET_TESTING_system_destory()}. This function takes the handle of
1699the system and a flag to remove the files created in the directory used
1700to generate configurations.
1701
1702A peer is created with the function
1703@code{GNUNET_TESTING_peer_configure()}. This functions takes the system
1704handle, a configuration template from which the configuration for the peer
1705is auto-generated and the index from where the hostkey for the peer has to
1706be copied from. When successful, this function returns a handle to the
1707peer which can be used to start and stop it and to obtain the identity of
1708the peer. If unsuccessful, a NULL pointer is returned with an error
1709message. This function handles the generated configuration to have
1710non-conflicting ports and paths.
1711
1712Peers can be started and stopped by calling the functions
1713@code{GNUNET_TESTING_peer_start()} and @code{GNUNET_TESTING_peer_stop()}
1714respectively. A peer can be destroyed by calling the function
1715@code{GNUNET_TESTING_peer_destroy}. When a peer is destroyed, the ports
1716and paths in allocated in its configuration are reclaimed for usage in new
1717peers.
1718
1719@c ***********************************************************************
1720@node Finer control over peer stop
1721@subsection Finer control over peer stop
1722
1723Using @code{GNUNET_TESTING_peer_stop()} is normally fine for testcases.
1724However, calling this function for each peer is inefficient when trying to
1725shutdown multiple peers as this function sends the termination signal to
1726the given peer process and waits for it to terminate. It would be faster
1727in this case to send the termination signals to the peers first and then
1728wait on them. This is accomplished by the functions
1729@code{GNUNET_TESTING_peer_kill()} which sends a termination signal to the
1730peer, and the function @code{GNUNET_TESTING_peer_wait()} which waits on
1731the peer.
1732
1733Further finer control can be achieved by choosing to stop a peer
1734asynchronously with the function @code{GNUNET_TESTING_peer_stop_async()}.
1735This function takes a callback parameter and a closure for it in addition
1736to the handle to the peer to stop. The callback function is called with
1737the given closure when the peer is stopped. Using this function
1738eliminates blocking while waiting for the peer to terminate.
1739
1740An asynchronous peer stop can be canceled by calling the function
1741@code{GNUNET_TESTING_peer_stop_async_cancel()}. Note that calling this
1742function does not prevent the peer from terminating if the termination
1743signal has already been sent to it. It does, however, cancels the
1744callback to be called when the peer is stopped.
1745
1746@c ***********************************************************************
1747@node Helper functions
1748@subsection Helper functions
1749
1750Most of the testcases can benefit from an abstraction which configures a
1751peer and starts it. This is provided by the function
1752@code{GNUNET_TESTING_peer_run()}. This function takes the testing
1753directory pathname, a configuration template, a callback and its closure.
1754This function creates a peer in the given testing directory by using the
1755configuration template, starts the peer and calls the given callback with
1756the given closure.
1757
1758The function @code{GNUNET_TESTING_peer_run()} starts the ARM service of
1759the peer which starts the rest of the configured services. A similar
1760function @code{GNUNET_TESTING_service_run} can be used to just start a
1761single service of a peer. In this case, the peer's ARM service is not
1762started; instead, only the given service is run.
1763
1764@c ***********************************************************************
1765@node Testing with multiple processes
1766@subsection Testing with multiple processes
1767
1768When testing GNUnet, the splitting of the code into a services and clients
1769often complicates testing. The solution to this is to have the testcase
1770fork @code{gnunet-service-arm}, ask it to start the required server and
1771daemon processes and then execute appropriate client actions (to test the
1772client APIs or the core module or both). If necessary, multiple ARM
1773services can be forked using different ports (!) to simulate a network.
1774However, most of the time only one ARM process is needed. Note that on
1775exit, the testcase should shutdown ARM with a @code{TERM} signal (to give
1776it the chance to cleanly stop its child processes).
1777
1778@c TODO: Is this still compiling and working as intended?
1779The following code illustrates spawning and killing an ARM process from a
1780testcase:
1781
1782@example
1783static void run (void *cls,
1784 char *const *args,
1785 const char *cfgfile,
1786 const struct GNUNET_CONFIGURATION_Handle *cfg) @{
1787 struct GNUNET_OS_Process *arm_pid;
1788 arm_pid = GNUNET_OS_start_process (NULL,
1789 NULL,
1790 "gnunet-service-arm",
1791 "gnunet-service-arm",
1792 "-c",
1793 cfgname,
1794 NULL);
1795 /* do real test work here */
1796 if (0 != GNUNET_OS_process_kill (arm_pid, SIGTERM))
1797 GNUNET_log_strerror
1798 (GNUNET_ERROR_TYPE_WARNING, "kill");
1799 GNUNET_assert (GNUNET_OK == GNUNET_OS_process_wait (arm_pid));
1800 GNUNET_OS_process_close (arm_pid); @}
1801
1802GNUNET_PROGRAM_run (argc, argv,
1803 "NAME-OF-TEST",
1804 "nohelp",
1805 options,
1806 &run,
1807 cls);
1808@end example
1809
1810
1811An alternative way that works well to test plugins is to implement a
1812mock-version of the environment that the plugin expects and then to
1813simply load the plugin directly.
1814
1815@c ***********************************************************************
1816@node Performance regression analysis with Gauger
1817@section Performance regression analysis with Gauger
1818
1819To help avoid performance regressions, GNUnet uses Gauger. Gauger is a
1820simple logging tool that allows remote hosts to send performance data to
1821a central server, where this data can be analyzed and visualized. Gauger
1822shows graphs of the repository revisions and the performance data recorded
1823for each revision, so sudden performance peaks or drops can be identified
1824and linked to a specific revision number.
1825
1826In the case of GNUnet, the buildbots log the performance data obtained
1827during the tests after each build. The data can be accessed on GNUnet's
1828Gauger page.
1829
1830The menu on the left allows to select either the results of just one
1831build bot (under "Hosts") or review the data from all hosts for a given
1832test result (under "Metrics"). In case of very different absolute value
1833of the results, for instance arm vs. amd64 machines, the option
1834"Normalize" on a metric view can help to get an idea about the
1835performance evolution across all hosts.
1836
1837Using Gauger in GNUnet and having the performance of a module tracked over
1838time is very easy. First of course, the testcase must generate some
1839consistent metric, which makes sense to have logged. Highly volatile or
1840random dependent metrics probably are not ideal candidates for meaningful
1841regression detection.
1842
1843To start logging any value, just include @code{gauger.h} in your testcase
1844code. Then, use the macro @code{GAUGER()} to make the Buildbots log
1845whatever value is of interest for you to @code{gnunet.org}'s Gauger
1846server. No setup is necessary as most Buildbots have already everything
1847in place and new metrics are created on demand. To delete a metric, you
1848need to contact a member of the GNUnet development team (a file will need
1849to be removed manually from the respective directory).
1850
1851The code in the test should look like this:
1852
1853@example
1854[other includes]
1855#include <gauger.h>
1856
1857int main (int argc, char *argv[]) @{
1858
1859 [run test, generate data]
1860 GAUGER("YOUR_MODULE",
1861 "METRIC_NAME",
1862 (float)value,
1863 "UNIT"); @}
1864@end example
1865
1866Where:
1867
1868@table @asis
1869
1870@item @strong{YOUR_MODULE} is a category in the gauger page and should be
1871the name of the module or subsystem like "Core" or "DHT"
1872@item @strong{METRIC} is
1873the name of the metric being collected and should be concise and
1874descriptive, like "PUT operations in sqlite-datastore".
1875@item @strong{value} is the value
1876of the metric that is logged for this run.
1877@item @strong{UNIT} is the unit in
1878which the value is measured, for instance "kb/s" or "kb of RAM/node".
1879@end table
1880
1881If you wish to use Gauger for your own project, you can grab a copy of the
1882latest stable release or check out Gauger's Subversion repository.
1883
1884@cindex TESTBED Subsystem
1885@node TESTBED Subsystem
1886@section TESTBED Subsystem
1887
1888The TESTBED subsystem facilitates testing and measuring of multi-peer
1889deployments on a single host or over multiple hosts.
1890
1891The architecture of the testbed module is divided into the following:
1892@itemize @bullet
1893
1894@item Testbed API: An API which is used by the testing driver programs. It
1895provides with functions for creating, destroying, starting, stopping
1896peers, etc.
1897
1898@item Testbed service (controller): A service which is started through the
1899Testbed API. This service handles operations to create, destroy, start,
1900stop peers, connect them, modify their configurations.
1901
1902@item Testbed helper: When a controller has to be started on a host, the
1903testbed API starts the testbed helper on that host which in turn starts
1904the controller. The testbed helper receives a configuration for the
1905controller through its stdin and changes it to ensure the controller
1906doesn't run into any port conflict on that host.
1907@end itemize
1908
1909
1910The testbed service (controller) is different from the other GNUnet
1911services in that it is not started by ARM and is not supposed to be run
1912as a daemon. It is started by the testbed API through a testbed helper.
1913In a typical scenario involving multiple hosts, a controller is started
1914on each host. Controllers take up the actual task of creating peers,
1915starting and stopping them on the hosts they run.
1916
1917While running deployments on a single localhost the testbed API starts the
1918testbed helper directly as a child process. When running deployments on
1919remote hosts the testbed API starts Testbed Helpers on each remote host
1920through remote shell. By default testbed API uses SSH as a remote shell.
1921This can be changed by setting the environmental variable
1922GNUNET_TESTBED_RSH_CMD to the required remote shell program. This
1923variable can also contain parameters which are to be passed to the remote
1924shell program. For e.g:
1925
1926@example
1927export GNUNET_TESTBED_RSH_CMD="ssh -o BatchMode=yes \
1928-o NoHostAuthenticationForLocalhost=yes %h"
1929@end example
1930
1931Substitutions are allowed in the command string above,
1932this allows for substitutions through placemarks which begin with a `%'.
1933At present the following substitutions are supported
1934
1935@itemize @bullet
1936@item %h: hostname
1937@item %u: username
1938@item %p: port
1939@end itemize
1940
1941Note that the substitution placemark is replaced only when the
1942corresponding field is available and only once. Specifying
1943
1944@example
1945%u@@%h
1946@end example
1947
1948doesn't work either. If you want to user username substitutions for
1949@command{SSH}, use the argument @code{-l} before the
1950username substitution.
1951
1952For example:
1953@example
1954ssh -l %u -p %p %h
1955@end example
1956
1957The testbed API and the helper communicate through the helpers stdin and
1958stdout. As the helper is started through a remote shell on remote hosts
1959any output messages from the remote shell interfere with the communication
1960and results in a failure while starting the helper. For this reason, it is
1961suggested to use flags to make the remote shells produce no output
1962messages and to have password-less logins. The default remote shell, SSH,
1963the default options are:
1964
1965@example
1966-o BatchMode=yes -o NoHostBasedAuthenticationForLocalhost=yes"
1967@end example
1968
1969Password-less logins should be ensured by using SSH keys.
1970
1971Since the testbed API executes the remote shell as a non-interactive
1972shell, certain scripts like .bashrc, .profiler may not be executed. If
1973this is the case testbed API can be forced to execute an interactive
1974shell by setting up the environmental variable
1975@code{GNUNET_TESTBED_RSH_CMD_SUFFIX} to a shell program.
1976
1977An example could be:
1978
1979@example
1980export GNUNET_TESTBED_RSH_CMD_SUFFIX="sh -lc"
1981@end example
1982
1983The testbed API will then execute the remote shell program as:
1984
1985@example
1986$GNUNET_TESTBED_RSH_CMD -p $port $dest $GNUNET_TESTBED_RSH_CMD_SUFFIX \
1987gnunet-helper-testbed
1988@end example
1989
1990On some systems, problems may arise while starting testbed helpers if
1991GNUnet is installed into a custom location since the helper may not be
1992found in the standard path. This can be addressed by setting the variable
1993`@code{HELPER_BINARY_PATH}' to the path of the testbed helper.
1994Testbed API will then use this path to start helper binaries both
1995locally and remotely.
1996
1997Testbed API can accessed by including the
1998@file{gnunet_testbed_service.h} file and linking with
1999@code{-lgnunettestbed}.
2000
2001@c ***********************************************************************
2002@menu
2003* Supported Topologies::
2004* Hosts file format::
2005* Topology file format::
2006* Testbed Barriers::
2007* TESTBED Caveats::
2008@end menu
2009
2010@node Supported Topologies
2011@subsection Supported Topologies
2012
2013While testing multi-peer deployments, it is often needed that the peers
2014are connected in some topology. This requirement is addressed by the
2015function @code{GNUNET_TESTBED_overlay_connect()} which connects any given
2016two peers in the testbed.
2017
2018The API also provides a helper function
2019@code{GNUNET_TESTBED_overlay_configure_topology()} to connect a given set
2020of peers in any of the following supported topologies:
2021
2022@itemize @bullet
2023
2024@item @code{GNUNET_TESTBED_TOPOLOGY_CLIQUE}: All peers are connected with
2025each other
2026
2027@item @code{GNUNET_TESTBED_TOPOLOGY_LINE}: Peers are connected to form a
2028line
2029
2030@item @code{GNUNET_TESTBED_TOPOLOGY_RING}: Peers are connected to form a
2031ring topology
2032
2033@item @code{GNUNET_TESTBED_TOPOLOGY_2D_TORUS}: Peers are connected to
2034form a 2 dimensional torus topology. The number of peers may not be a
2035perfect square, in that case the resulting torus may not have the uniform
2036poloidal and toroidal lengths
2037
2038@item @code{GNUNET_TESTBED_TOPOLOGY_ERDOS_RENYI}: Topology is generated
2039to form a random graph. The number of links to be present should be given
2040
2041@item @code{GNUNET_TESTBED_TOPOLOGY_SMALL_WORLD}: Peers are connected to
2042form a 2D Torus with some random links among them. The number of random
2043links are to be given
2044
2045@item @code{GNUNET_TESTBED_TOPOLOGY_SMALL_WORLD_RING}: Peers are
2046connected to form a ring with some random links among them. The number of
2047random links are to be given
2048
2049@item @code{GNUNET_TESTBED_TOPOLOGY_SCALE_FREE}: Connects peers in a
2050topology where peer connectivity follows power law - new peers are
2051connected with high probability to well connected peers.
2052(See Emergence of Scaling in Random Networks. Science 286,
2053509-512, 1999
2054(@uref{https://git.gnunet.org/bibliography.git/plain/docs/emergence_of_scaling_in_random_networks__barabasi_albert_science_286__1999.pdf, pdf}))
2055
2056@item @code{GNUNET_TESTBED_TOPOLOGY_FROM_FILE}: The topology information
2057is loaded from a file. The path to the file has to be given.
2058@xref{Topology file format}, for the format of this file.
2059
2060@item @code{GNUNET_TESTBED_TOPOLOGY_NONE}: No topology
2061@end itemize
2062
2063
2064The above supported topologies can be specified respectively by setting
2065the variable @code{OVERLAY_TOPOLOGY} to the following values in the
2066configuration passed to Testbed API functions
2067@code{GNUNET_TESTBED_test_run()} and
2068@code{GNUNET_TESTBED_run()}:
2069
2070@itemize @bullet
2071@item @code{CLIQUE}
2072@item @code{RING}
2073@item @code{LINE}
2074@item @code{2D_TORUS}
2075@item @code{RANDOM}
2076@item @code{SMALL_WORLD}
2077@item @code{SMALL_WORLD_RING}
2078@item @code{SCALE_FREE}
2079@item @code{FROM_FILE}
2080@item @code{NONE}
2081@end itemize
2082
2083
2084Topologies @code{RANDOM}, @code{SMALL_WORLD} and @code{SMALL_WORLD_RING}
2085require the option @code{OVERLAY_RANDOM_LINKS} to be set to the number of
2086random links to be generated in the configuration. The option will be
2087ignored for the rest of the topologies.
2088
2089Topology @code{SCALE_FREE} requires the options
2090@code{SCALE_FREE_TOPOLOGY_CAP} to be set to the maximum number of peers
2091which can connect to a peer and @code{SCALE_FREE_TOPOLOGY_M} to be set to
2092how many peers a peer should be at least connected to.
2093
2094Similarly, the topology @code{FROM_FILE} requires the option
2095@code{OVERLAY_TOPOLOGY_FILE} to contain the path of the file containing
2096the topology information. This option is ignored for the rest of the
2097topologies. @xref{Topology file format}, for the format of this file.
2098
2099@c ***********************************************************************
2100@node Hosts file format
2101@subsection Hosts file format
2102
2103The testbed API offers the function
2104@code{GNUNET_TESTBED_hosts_load_from_file()} to load from a given file
2105details about the hosts which testbed can use for deploying peers.
2106This function is useful to keep the data about hosts
2107separate instead of hard coding them in code.
2108
2109Another helper function from testbed API, @code{GNUNET_TESTBED_run()}
2110also takes a hosts file name as its parameter. It uses the above
2111function to populate the hosts data structures and start controllers to
2112deploy peers.
2113
2114These functions require the hosts file to be of the following format:
2115@itemize @bullet
2116@item Each line is interpreted to have details about a host
2117@item Host details should include the username to use for logging into the
2118host, the hostname of the host and the port number to use for the remote
2119shell program. All thee values should be given.
2120@item These details should be given in the following format:
2121@example
2122<username>@@<hostname>:<port>
2123@end example
2124@end itemize
2125
2126Note that having canonical hostnames may cause problems while resolving
2127the IP addresses (See this bug). Hence it is advised to provide the hosts'
2128IP numerical addresses as hostnames whenever possible.
2129
2130@c ***********************************************************************
2131@node Topology file format
2132@subsection Topology file format
2133
2134A topology file describes how peers are to be connected. It should adhere
2135to the following format for testbed to parse it correctly.
2136
2137Each line should begin with the target peer id. This should be followed by
2138a colon(`:') and origin peer ids separated by `|'. All spaces except for
2139newline characters are ignored. The API will then try to connect each
2140origin peer to the target peer.
2141
2142For example, the following file will result in 5 overlay connections:
2143[2->1], [3->1],[4->3], [0->3], [2->0]@
2144@code{@ 1:2|3@ 3:4| 0@ 0: 2@ }
2145
2146@c ***********************************************************************
2147@node Testbed Barriers
2148@subsection Testbed Barriers
2149
2150The testbed subsystem's barriers API facilitates coordination among the
2151peers run by the testbed and the experiment driver. The concept is
2152similar to the barrier synchronisation mechanism found in parallel
2153programming or multi-threading paradigms - a peer waits at a barrier upon
2154reaching it until the barrier is reached by a predefined number of peers.
2155This predefined number of peers required to cross a barrier is also called
2156quorum. We say a peer has reached a barrier if the peer is waiting for the
2157barrier to be crossed. Similarly a barrier is said to be reached if the
2158required quorum of peers reach the barrier. A barrier which is reached is
2159deemed as crossed after all the peers waiting on it are notified.
2160
2161The barriers API provides the following functions:
2162@itemize @bullet
2163@item @strong{@code{GNUNET_TESTBED_barrier_init()}:} function to
2164initialize a barrier in the experiment
2165@item @strong{@code{GNUNET_TESTBED_barrier_cancel()}:} function to cancel
2166a barrier which has been initialized before
2167@item @strong{@code{GNUNET_TESTBED_barrier_wait()}:} function to signal
2168barrier service that the caller has reached a barrier and is waiting for
2169it to be crossed
2170@item @strong{@code{GNUNET_TESTBED_barrier_wait_cancel()}:} function to
2171stop waiting for a barrier to be crossed
2172@end itemize
2173
2174
2175Among the above functions, the first two, namely
2176@code{GNUNET_TESTBED_barrier_init()} and
2177@code{GNUNET_TESTBED_barrier_cancel()} are used by experiment drivers. All
2178barriers should be initialised by the experiment driver by calling
2179@code{GNUNET_TESTBED_barrier_init()}. This function takes a name to
2180identify the barrier, the quorum required for the barrier to be crossed
2181and a notification callback for notifying the experiment driver when the
2182barrier is crossed. @code{GNUNET_TESTBED_barrier_cancel()} cancels an
2183initialised barrier and frees the resources allocated for it. This
2184function can be called upon a initialised barrier before it is crossed.
2185
2186The remaining two functions @code{GNUNET_TESTBED_barrier_wait()} and
2187@code{GNUNET_TESTBED_barrier_wait_cancel()} are used in the peer's
2188processes. @code{GNUNET_TESTBED_barrier_wait()} connects to the local
2189barrier service running on the same host the peer is running on and
2190registers that the caller has reached the barrier and is waiting for the
2191barrier to be crossed. Note that this function can only be used by peers
2192which are started by testbed as this function tries to access the local
2193barrier service which is part of the testbed controller service. Calling
2194@code{GNUNET_TESTBED_barrier_wait()} on an uninitialised barrier results
2195in failure. @code{GNUNET_TESTBED_barrier_wait_cancel()} cancels the
2196notification registered by @code{GNUNET_TESTBED_barrier_wait()}.
2197
2198
2199@c ***********************************************************************
2200@menu
2201* Implementation::
2202@end menu
2203
2204@node Implementation
2205@subsubsection Implementation
2206
2207Since barriers involve coordination between experiment driver and peers,
2208the barrier service in the testbed controller is split into two
2209components. The first component responds to the message generated by the
2210barrier API used by the experiment driver (functions
2211@code{GNUNET_TESTBED_barrier_init()} and
2212@code{GNUNET_TESTBED_barrier_cancel()}) and the second component to the
2213messages generated by barrier API used by peers (functions
2214@code{GNUNET_TESTBED_barrier_wait()} and
2215@code{GNUNET_TESTBED_barrier_wait_cancel()}).
2216
2217Calling @code{GNUNET_TESTBED_barrier_init()} sends a
2218@code{GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_INIT} message to the master
2219controller. The master controller then registers a barrier and calls
2220@code{GNUNET_TESTBED_barrier_init()} for each its subcontrollers. In this
2221way barrier initialisation is propagated to the controller hierarchy.
2222While propagating initialisation, any errors at a subcontroller such as
2223timeout during further propagation are reported up the hierarchy back to
2224the experiment driver.
2225
2226Similar to @code{GNUNET_TESTBED_barrier_init()},
2227@code{GNUNET_TESTBED_barrier_cancel()} propagates
2228@code{GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_CANCEL} message which causes
2229controllers to remove an initialised barrier.
2230
2231The second component is implemented as a separate service in the binary
2232`gnunet-service-testbed' which already has the testbed controller service.
2233Although this deviates from the gnunet process architecture of having one
2234service per binary, it is needed in this case as this component needs
2235access to barrier data created by the first component. This component
2236responds to @code{GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_WAIT} messages from
2237local peers when they call @code{GNUNET_TESTBED_barrier_wait()}. Upon
2238receiving @code{GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_WAIT} message, the
2239service checks if the requested barrier has been initialised before and
2240if it was not initialised, an error status is sent through
2241@code{GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS} message to the local
2242peer and the connection from the peer is terminated. If the barrier is
2243initialised before, the barrier's counter for reached peers is incremented
2244and a notification is registered to notify the peer when the barrier is
2245reached. The connection from the peer is left open.
2246
2247When enough peers required to attain the quorum send
2248@code{GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_WAIT} messages, the controller
2249sends a @code{GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS} message to its
2250parent informing that the barrier is crossed. If the controller has
2251started further subcontrollers, it delays this message until it receives
2252a similar notification from each of those subcontrollers. Finally, the
2253barriers API at the experiment driver receives the
2254@code{GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS} when the barrier is
2255reached at all the controllers.
2256
2257The barriers API at the experiment driver responds to the
2258@code{GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS} message by echoing it
2259back to the master controller and notifying the experiment controller
2260through the notification callback that a barrier has been crossed. The
2261echoed @code{GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS} message is
2262propagated by the master controller to the controller hierarchy. This
2263propagation triggers the notifications registered by peers at each of the
2264controllers in the hierarchy. Note the difference between this downward
2265propagation of the @code{GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS}
2266message from its upward propagation --- the upward propagation is needed
2267for ensuring that the barrier is reached by all the controllers and the
2268downward propagation is for triggering that the barrier is crossed.
2269
2270@cindex TESTBED Caveats
2271@node TESTBED Caveats
2272@subsection TESTBED Caveats
2273
2274This section documents a few caveats when using the GNUnet testbed
2275subsystem.
2276
2277@c ***********************************************************************
2278@menu
2279* CORE must be started::
2280* ATS must want the connections::
2281@end menu
2282
2283@node CORE must be started
2284@subsubsection CORE must be started
2285
2286A uncomplicated issue is bug #3993
2287(@uref{https://bugs.gnunet.org/view.php?id=3993, https://bugs.gnunet.org/view.php?id=3993}):
2288Your configuration MUST somehow ensure that for each peer the
2289@code{CORE} service is started when the peer is setup, otherwise
2290@code{TESTBED} may fail to connect peers when the topology is initialized,
2291as @code{TESTBED} will start some @code{CORE} services but not
2292necessarily all (but it relies on all of them running). The easiest way
2293is to set
2294
2295@example
2296[core]
2297IMMEDIATE_START = YES
2298@end example
2299
2300@noindent
2301in the configuration file.
2302Alternatively, having any service that directly or indirectly depends on
2303@code{CORE} being started with @code{IMMEDIATE_START} will also do.
2304This issue largely arises if users try to over-optimize by not
2305starting any services with @code{IMMEDIATE_START}.
2306
2307@c ***********************************************************************
2308@node ATS must want the connections
2309@subsubsection ATS must want the connections
2310
2311When TESTBED sets up connections, it only offers the respective HELLO
2312information to the TRANSPORT service. It is then up to the ATS service to
2313@strong{decide} to use the connection. The ATS service will typically
2314eagerly establish any connection if the number of total connections is
2315low (relative to bandwidth). Details may further depend on the
2316specific ATS backend that was configured. If ATS decides to NOT establish
2317a connection (even though TESTBED provided the required information), then
2318that connection will count as failed for TESTBED. Note that you can
2319configure TESTBED to tolerate a certain number of connection failures
2320(see '-e' option of gnunet-testbed-profiler). This issue largely arises
2321for dense overlay topologies, especially if you try to create cliques
2322with more than 20 peers.
2323
2324@cindex libgnunetutil
2325@node libgnunetutil
2326@section libgnunetutil
2327
2328libgnunetutil is the fundamental library that all GNUnet code builds upon.
2329Ideally, this library should contain most of the platform dependent code
2330(except for user interfaces and really special needs that only few
2331applications have). It is also supposed to offer basic services that most
2332if not all GNUnet binaries require. The code of libgnunetutil is in the
2333@file{src/util/} directory. The public interface to the library is in the
2334gnunet_util.h header. The functions provided by libgnunetutil fall
2335roughly into the following categories (in roughly the order of importance
2336for new developers):
2337
2338@itemize @bullet
2339@item logging (common_logging.c)
2340@item memory allocation (common_allocation.c)
2341@item endianness conversion (common_endian.c)
2342@item internationalization (common_gettext.c)
2343@item String manipulation (string.c)
2344@item file access (disk.c)
2345@item buffered disk IO (bio.c)
2346@item time manipulation (time.c)
2347@item configuration parsing (configuration.c)
2348@item command-line handling (getopt*.c)
2349@item cryptography (crypto_*.c)
2350@item data structures (container_*.c)
2351@item CPS-style scheduling (scheduler.c)
2352@item Program initialization (program.c)
2353@item Networking (network.c, client.c, server*.c, service.c)
2354@item message queuing (mq.c)
2355@item bandwidth calculations (bandwidth.c)
2356@item Other OS-related (os*.c, plugin.c, signal.c)
2357@item Pseudonym management (pseudonym.c)
2358@end itemize
2359
2360It should be noted that only developers that fully understand this entire
2361API will be able to write good GNUnet code.
2362
2363Ideally, porting GNUnet should only require porting the gnunetutil
2364library. More testcases for the gnunetutil APIs are therefore a great
2365way to make porting of GNUnet easier.
2366
2367@menu
2368* Logging::
2369* Interprocess communication API (IPC)::
2370* Cryptography API::
2371* Message Queue API::
2372* Service API::
2373* Optimizing Memory Consumption of GNUnet's (Multi-) Hash Maps::
2374* CONTAINER_MDLL API::
2375@end menu
2376
2377@cindex Logging
2378@cindex log levels
2379@node Logging
2380@subsection Logging
2381
2382GNUnet is able to log its activity, mostly for the purposes of debugging
2383the program at various levels.
2384
2385@file{gnunet_common.h} defines several @strong{log levels}:
2386@table @asis
2387
2388@item ERROR for errors
2389(really problematic situations, often leading to crashes)
2390@item WARNING for warnings
2391(troubling situations that might have negative consequences, although
2392not fatal)
2393@item INFO for various information.
2394Used somewhat rarely, as GNUnet statistics is used to hold and display
2395most of the information that users might find interesting.
2396@item DEBUG for debugging.
2397Does not produce much output on normal builds, but when extra logging is
2398enabled at compile time, a staggering amount of data is outputted under
2399this log level.
2400@end table
2401
2402
2403Normal builds of GNUnet (configured with @code{--enable-logging[=yes]})
2404are supposed to log nothing under DEBUG level. The
2405@code{--enable-logging=verbose} configure option can be used to create a
2406build with all logging enabled. However, such build will produce large
2407amounts of log data, which is inconvenient when one tries to hunt down a
2408specific problem.
2409
2410To mitigate this problem, GNUnet provides facilities to apply a filter to
2411reduce the logs:
2412@table @asis
2413
2414@item Logging by default When no log levels are configured in any other
2415way (see below), GNUnet will default to the WARNING log level. This
2416mostly applies to GNUnet command line utilities, services and daemons;
2417tests will always set log level to WARNING or, if
2418@code{--enable-logging=verbose} was passed to configure, to DEBUG. The
2419default level is suggested for normal operation.
2420@item The -L option Most GNUnet executables accept an "-L loglevel" or
2421"--log=loglevel" option. If used, it makes the process set a global log
2422level to "loglevel". Thus it is possible to run some processes
2423with -L DEBUG, for example, and others with -L ERROR to enable specific
2424settings to diagnose problems with a particular process.
2425@item Configuration files. Because GNUnet
2426service and daemon processes are usually launched by gnunet-arm, it is not
2427possible to pass different custom command line options directly to every
2428one of them. The options passed to @code{gnunet-arm} only affect
2429gnunet-arm and not the rest of GNUnet. However, one can specify a
2430configuration key "OPTIONS" in the section that corresponds to a service
2431or a daemon, and put a value of "-L loglevel" there. This will make the
2432respective service or daemon set its log level to "loglevel" (as the
2433value of OPTIONS will be passed as a command-line argument).
2434
2435To specify the same log level for all services without creating separate
2436"OPTIONS" entries in the configuration for each one, the user can specify
2437a config key "GLOBAL_POSTFIX" in the [arm] section of the configuration
2438file. The value of GLOBAL_POSTFIX will be appended to all command lines
2439used by the ARM service to run other services. It can contain any option
2440valid for all GNUnet commands, thus in particular the "-L loglevel"
2441option. The ARM service itself is, however, unaffected by GLOBAL_POSTFIX;
2442to set log level for it, one has to specify "OPTIONS" key in the [arm]
2443section.
2444@item Environment variables.
2445Setting global per-process log levels with "-L loglevel" does not offer
2446sufficient log filtering granularity, as one service will call interface
2447libraries and supporting libraries of other GNUnet services, potentially
2448producing lots of debug log messages from these libraries. Also, changing
2449the config file is not always convenient (especially when running the
2450GNUnet test suite).@ To fix that, and to allow GNUnet to use different
2451log filtering at runtime without re-compiling the whole source tree, the
2452log calls were changed to be configurable at run time. To configure them
2453one has to define environment variables "GNUNET_FORCE_LOGFILE",
2454"GNUNET_LOG" and/or "GNUNET_FORCE_LOG":
2455@itemize @bullet
2456
2457@item "GNUNET_LOG" only affects the logging when no global log level is
2458configured by any other means (that is, the process does not explicitly
2459set its own log level, there are no "-L loglevel" options on command line
2460or in configuration files), and can be used to override the default
2461WARNING log level.
2462
2463@item "GNUNET_FORCE_LOG" will completely override any other log
2464configuration options given.
2465
2466@item "GNUNET_FORCE_LOGFILE" will completely override the location of the
2467file to log messages to. It should contain a relative or absolute file
2468name. Setting GNUNET_FORCE_LOGFILE is equivalent to passing
2469"--log-file=logfile" or "-l logfile" option (see below). It supports "[]"
2470format in file names, but not "@{@}" (see below).
2471@end itemize
2472
2473
2474Because environment variables are inherited by child processes when they
2475are launched, starting or re-starting the ARM service with these
2476variables will propagate them to all other services.
2477
2478"GNUNET_LOG" and "GNUNET_FORCE_LOG" variables must contain a specially
2479formatted @strong{logging definition} string, which looks like this:@
2480
2481@c FIXME: Can we close this with [/component] instead?
2482@example
2483[component];[file];[function];[from_line[-to_line]];loglevel[/component...]
2484@end example
2485
2486That is, a logging definition consists of definition entries, separated by
2487slashes ('/'). If only one entry is present, there is no need to add a
2488slash to its end (although it is not forbidden either).@ All definition
2489fields (component, file, function, lines and loglevel) are mandatory, but
2490(except for the loglevel) they can be empty. An empty field means
2491"match anything". Note that even if fields are empty, the semicolon (';')
2492separators must be present.@ The loglevel field is mandatory, and must
2493contain one of the log level names (ERROR, WARNING, INFO or DEBUG).@
2494The lines field might contain one non-negative number, in which case it
2495matches only one line, or a range "from_line-to_line", in which case it
2496matches any line in the interval [from_line;to_line] (that is, including
2497both start and end line).@ GNUnet mostly defaults component name to the
2498name of the service that is implemented in a process ('transport',
2499'core', 'peerinfo', etc), but logging calls can specify custom component
2500names using @code{GNUNET_log_from}.@ File name and function name are
2501provided by the compiler (__FILE__ and __FUNCTION__ built-ins).
2502
2503Component, file and function fields are interpreted as non-extended
2504regular expressions (GNU libc regex functions are used). Matching is
2505case-sensitive, "^" and "$" will match the beginning and the end of the
2506text. If a field is empty, its contents are automatically replaced with
2507a ".*" regular expression, which matches anything. Matching is done in
2508the default way, which means that the expression matches as long as it's
2509contained anywhere in the string. Thus "GNUNET_" will match both
2510"GNUNET_foo" and "BAR_GNUNET_BAZ". Use '^' and/or '$' to make sure that
2511the expression matches at the start and/or at the end of the string.
2512The semicolon (';') can't be escaped, and GNUnet will not use it in
2513component names (it can't be used in function names and file names
2514anyway).
2515
2516@end table
2517
2518
2519Every logging call in GNUnet code will be (at run time) matched against
2520the log definitions passed to the process. If a log definition fields are
2521matching the call arguments, then the call log level is compared to the
2522log level of that definition. If the call log level is less or equal to
2523the definition log level, the call is allowed to proceed. Otherwise the
2524logging call is forbidden, and nothing is logged. If no definitions
2525matched at all, GNUnet will use the global log level or (if a global log
2526level is not specified) will default to WARNING (that is, it will allow
2527the call to proceed, if its level is less or equal to the global log
2528level or to WARNING).
2529
2530That is, definitions are evaluated from left to right, and the first
2531matching definition is used to allow or deny the logging call. Thus it is
2532advised to place narrow definitions at the beginning of the logdef
2533string, and generic definitions - at the end.
2534
2535Whether a call is allowed or not is only decided the first time this
2536particular call is made. The evaluation result is then cached, so that
2537any attempts to make the same call later will be allowed or disallowed
2538right away. Because of that runtime log level evaluation should not
2539significantly affect the process performance.
2540Log definition parsing is only done once, at the first call to
2541@code{GNUNET_log_setup ()} made by the process (which is usually
2542done soon after it starts).
2543
2544At the moment of writing there is no way to specify logging definitions
2545from configuration files, only via environment variables.
2546
2547At the moment GNUnet will stop processing a log definition when it
2548encounters an error in definition formatting or an error in regular
2549expression syntax, and will not report the failure in any way.
2550
2551
2552@c ***********************************************************************
2553@menu
2554* Examples::
2555* Log files::
2556* Updated behavior of GNUNET_log::
2557@end menu
2558
2559@node Examples
2560@subsubsection Examples
2561
2562@table @asis
2563
2564@item @code{GNUNET_FORCE_LOG=";;;;DEBUG" gnunet-arm -s} Start GNUnet
2565process tree, running all processes with DEBUG level (one should be
2566careful with it, as log files will grow at alarming rate!)
2567@item @code{GNUNET_FORCE_LOG="core;;;;DEBUG" gnunet-arm -s} Start GNUnet
2568process tree, running the core service under DEBUG level (everything else
2569will use configured or default level).
2570
2571@item Start GNUnet process tree, allowing any logging calls from
2572gnunet-service-transport_validation.c (everything else will use
2573configured or default level).
2574
2575@example
2576GNUNET_FORCE_LOG=";gnunet-service-transport_validation.c;;; DEBUG" \
2577gnunet-arm -s
2578@end example
2579
2580@item Start GNUnet process tree, allowing any logging calls from
2581gnunet-gnunet-service-fs_push.c (everything else will use configured or
2582default level).
2583
2584@example
2585GNUNET_FORCE_LOG="fs;gnunet-service-fs_push.c;;;DEBUG" gnunet-arm -s
2586@end example
2587
2588@item Start GNUnet process tree, allowing any logging calls from the
2589GNUNET_NETWORK_socket_select function (everything else will use
2590configured or default level).
2591
2592@example
2593GNUNET_FORCE_LOG=";;GNUNET_NETWORK_socket_select;;DEBUG" gnunet-arm -s
2594@end example
2595
2596@item Start GNUnet process tree, allowing any logging calls from the
2597components that have "transport" in their names, and are made from
2598function that have "send" in their names. Everything else will be allowed
2599to be logged only if it has WARNING level.
2600
2601@example
2602GNUNET_FORCE_LOG="transport.*;;.*send.*;;DEBUG/;;;;WARNING" gnunet-arm -s
2603@end example
2604
2605@end table
2606
2607
2608On Windows, one can use batch files to run GNUnet processes with special
2609environment variables, without affecting the whole system. Such batch
2610file will look like this:
2611
2612@example
2613set GNUNET_FORCE_LOG=;;do_transmit;;DEBUG@ gnunet-arm -s
2614@end example
2615
2616(note the absence of double quotes in the environment variable definition,
2617as opposed to earlier examples, which use the shell).
2618Another limitation, on Windows, GNUNET_FORCE_LOGFILE @strong{MUST} be set
2619in order to GNUNET_FORCE_LOG to work.
2620
2621
2622@cindex Log files
2623@node Log files
2624@subsubsection Log files
2625
2626GNUnet can be told to log everything into a file instead of stderr (which
2627is the default) using the "--log-file=logfile" or "-l logfile" option.
2628This option can also be passed via command line, or from the "OPTION" and
2629"GLOBAL_POSTFIX" configuration keys (see above). The file name passed
2630with this option is subject to GNUnet filename expansion. If specified in
2631"GLOBAL_POSTFIX", it is also subject to ARM service filename expansion,
2632in particular, it may contain "@{@}" (left and right curly brace)
2633sequence, which will be replaced by ARM with the name of the service.
2634This is used to keep logs from more than one service separate, while only
2635specifying one template containing "@{@}" in GLOBAL_POSTFIX.
2636
2637As part of a secondary file name expansion, the first occurrence of "[]"
2638sequence ("left square brace" followed by "right square brace") in the
2639file name will be replaced with a process identifier or the process when
2640it initializes its logging subsystem. As a result, all processes will log
2641into different files. This is convenient for isolating messages of a
2642particular process, and prevents I/O races when multiple processes try to
2643write into the file at the same time. This expansion is done
2644independently of "@{@}" expansion that ARM service does (see above).
2645
2646The log file name that is specified via "-l" can contain format characters
2647from the 'strftime' function family. For example, "%Y" will be replaced
2648with the current year. Using "basename-%Y-%m-%d.log" would include the
2649current year, month and day in the log file. If a GNUnet process runs for
2650long enough to need more than one log file, it will eventually clean up
2651old log files. Currently, only the last three log files (plus the current
2652log file) are preserved. So once the fifth log file goes into use (so
2653after 4 days if you use "%Y-%m-%d" as above), the first log file will be
2654automatically deleted. Note that if your log file name only contains "%Y",
2655then log files would be kept for 4 years and the logs from the first year
2656would be deleted once year 5 begins. If you do not use any date-related
2657string format codes, logs would never be automatically deleted by GNUnet.
2658
2659
2660@c ***********************************************************************
2661
2662@node Updated behavior of GNUNET_log
2663@subsubsection Updated behavior of GNUNET_log
2664
2665It's currently quite common to see constructions like this all over the
2666code:
2667
2668@example
2669#if MESH_DEBUG
2670GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: client disconnected\n");
2671#endif
2672@end example
2673
2674The reason for the #if is not to avoid displaying the message when
2675disabled (GNUNET_ERROR_TYPE takes care of that), but to avoid the
2676compiler including it in the binary at all, when compiling GNUnet for
2677platforms with restricted storage space / memory (MIPS routers,
2678ARM plug computers / dev boards, etc).
2679
2680This presents several problems: the code gets ugly, hard to write and it
2681is very easy to forget to include the #if guards, creating non-consistent
2682code. A new change in GNUNET_log aims to solve these problems.
2683
2684@strong{This change requires to @file{./configure} with at least
2685@code{--enable-logging=verbose} to see debug messages.}
2686
2687Here is an example of code with dense debug statements:
2688
2689@example
2690switch (restrict_topology) @{
2691case GNUNET_TESTING_TOPOLOGY_CLIQUE:#if VERBOSE_TESTING
2692GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Blacklisting all but clique
2693topology\n")); #endif unblacklisted_connections = create_clique (pg,
2694&remove_connections, BLACKLIST, GNUNET_NO); break; case
2695GNUNET_TESTING_TOPOLOGY_SMALL_WORLD_RING: #if VERBOSE_TESTING GNUNET_log
2696(GNUNET_ERROR_TYPE_DEBUG, _("Blacklisting all but small world (ring)
2697topology\n")); #endif unblacklisted_connections = create_small_world_ring
2698(pg,&remove_connections, BLACKLIST); break;
2699@end example
2700
2701
2702Pretty hard to follow, huh?
2703
2704From now on, it is not necessary to include the #if / #endif statements to
2705achieve the same behavior. The @code{GNUNET_log} and @code{GNUNET_log_from}
2706macros take care of it for you, depending on the configure option:
2707
2708@itemize @bullet
2709@item If @code{--enable-logging} is set to @code{no}, the binary will
2710contain no log messages at all.
2711@item If @code{--enable-logging} is set to @code{yes}, the binary will
2712contain no DEBUG messages, and therefore running with @command{-L DEBUG}
2713will have
2714no effect. Other messages (ERROR, WARNING, INFO, etc) will be included.
2715@item If @code{--enable-logging} is set to @code{verbose}, or
2716@code{veryverbose} the binary will contain DEBUG messages (still, it will
2717be necessary to run with @command{-L DEBUG} or set the DEBUG config option
2718to show them).
2719@end itemize
2720
2721
2722If you are a developer:
2723@itemize @bullet
2724@item please make sure that you @code{./configure
2725--enable-logging=@{verbose,veryverbose@}}, so you can see DEBUG messages.
2726@item please remove the @code{#if} statements around @code{GNUNET_log
2727(GNUNET_ERROR_TYPE_DEBUG, ...)} lines, to improve the readability of your
2728code.
2729@end itemize
2730
2731Since now activating DEBUG automatically makes it VERBOSE and activates
2732@strong{all} debug messages by default, you probably want to use the
2733@uref{https://docs.gnunet.org/#Logging, https://docs.gnunet.org/#Logging}
2734functionality to filter only relevant messages.
2735A suitable configuration could be:
2736
2737@example
2738$ export GNUNET_FORCE_LOG="^YOUR_SUBSYSTEM$;;;;DEBUG/;;;;WARNING"
2739@end example
2740
2741Which will behave almost like enabling DEBUG in that subsystem before the
2742change. Of course you can adapt it to your particular needs, this is only
2743a quick example.
2744
2745@cindex Interprocess communication API
2746@cindex ICP
2747@node Interprocess communication API (IPC)
2748@subsection Interprocess communication API (IPC)
2749
2750In GNUnet a variety of new message types might be defined and used in
2751interprocess communication, in this tutorial we use the
2752@code{struct AddressLookupMessage} as a example to introduce how to
2753construct our own message type in GNUnet and how to implement the message
2754communication between service and client.
2755(Here, a client uses the @code{struct AddressLookupMessage} as a request
2756to ask the server to return the address of any other peer connecting to
2757the service.)
2758
2759
2760@c ***********************************************************************
2761@menu
2762* Define new message types::
2763* Define message struct::
2764* Client - Establish connection::
2765* Client - Initialize request message::
2766* Client - Send request and receive response::
2767* Server - Startup service::
2768* Server - Add new handles for specified messages::
2769* Server - Process request message::
2770* Server - Response to client::
2771* Server - Notification of clients::
2772* Conversion between Network Byte Order (Big Endian) and Host Byte Order::
2773@end menu
2774
2775@node Define new message types
2776@subsubsection Define new message types
2777
2778First of all, you should define the new message type in
2779@file{gnunet_protocols.h}:
2780
2781@example
2782 // Request to look addresses of peers in server.
2783#define GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_LOOKUP 29
2784 // Response to the address lookup request.
2785#define GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_REPLY 30
2786@end example
2787
2788@c ***********************************************************************
2789@node Define message struct
2790@subsubsection Define message struct
2791
2792After the type definition, the specified message structure should also be
2793described in the header file, e.g. transport.h in our case.
2794
2795@example
2796struct AddressLookupMessage @{
2797 struct GNUNET_MessageHeader header;
2798 int32_t numeric_only GNUNET_PACKED;
2799 struct GNUNET_TIME_AbsoluteNBO timeout;
2800 uint32_t addrlen GNUNET_PACKED;
2801 /* followed by 'addrlen' bytes of the actual address, then
2802 followed by the 0-terminated name of the transport */ @};
2803GNUNET_NETWORK_STRUCT_END
2804@end example
2805
2806
2807Please note @code{GNUNET_NETWORK_STRUCT_BEGIN} and @code{GNUNET_PACKED}
2808which both ensure correct alignment when sending structs over the network.
2809
2810@menu
2811@end menu
2812
2813@c ***********************************************************************
2814@node Client - Establish connection
2815@subsubsection Client - Establish connection
2816
2817
2818
2819At first, on the client side, the underlying API is employed to create a
2820new connection to a service, in our example the transport service would be
2821connected.
2822
2823@example
2824struct GNUNET_CLIENT_Connection *client;
2825client = GNUNET_CLIENT_connect ("transport", cfg);
2826@end example
2827
2828@c ***********************************************************************
2829@node Client - Initialize request message
2830@subsubsection Client - Initialize request message
2831
2832
2833When the connection is ready, we initialize the message. In this step,
2834all the fields of the message should be properly initialized, namely the
2835size, type, and some extra user-defined data, such as timeout, name of
2836transport, address and name of transport.
2837
2838@example
2839struct AddressLookupMessage *msg;
2840size_t len = sizeof (struct AddressLookupMessage)
2841 + addressLen
2842 + strlen (nameTrans)
2843 + 1;
2844msg->header->size = htons (len);
2845msg->header->type = htons
2846(GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_LOOKUP);
2847msg->timeout = GNUNET_TIME_absolute_hton (abs_timeout);
2848msg->addrlen = htonl (addressLen);
2849char *addrbuf = (char *) &msg[1];
2850memcpy (addrbuf, address, addressLen);
2851char *tbuf = &addrbuf[addressLen];
2852memcpy (tbuf, nameTrans, strlen (nameTrans) + 1);
2853@end example
2854
2855Note that, here the functions @code{htonl}, @code{htons} and
2856@code{GNUNET_TIME_absolute_hton} are applied to convert little endian
2857into big endian, about the usage of the big/small endian order and the
2858corresponding conversion function please refer to Introduction of
2859Big Endian and Little Endian.
2860
2861@c ***********************************************************************
2862@node Client - Send request and receive response
2863@subsubsection Client - Send request and receive response
2864
2865
2866@b{FIXME: This is very outdated, see the tutorial for the current API!}
2867
2868Next, the client would send the constructed message as a request to the
2869service and wait for the response from the service. To accomplish this
2870goal, there are a number of API calls that can be used. In this example,
2871@code{GNUNET_CLIENT_transmit_and_get_response} is chosen as the most
2872appropriate function to use.
2873
2874@example
2875GNUNET_CLIENT_transmit_and_get_response
2876(client, msg->header, timeout, GNUNET_YES, &address_response_processor,
2877arp_ctx);
2878@end example
2879
2880the argument @code{address_response_processor} is a function with
2881@code{GNUNET_CLIENT_MessageHandler} type, which is used to process the
2882reply message from the service.
2883
2884@node Server - Startup service
2885@subsubsection Server - Startup service
2886
2887After receiving the request message, we run a standard GNUnet service
2888startup sequence using @code{GNUNET_SERVICE_run}, as follows,
2889
2890@example
2891int main(int argc, char**argv) @{
2892 GNUNET_SERVICE_run(argc, argv, "transport"
2893 GNUNET_SERVICE_OPTION_NONE, &run, NULL)); @}
2894@end example
2895
2896@c ***********************************************************************
2897@node Server - Add new handles for specified messages
2898@subsubsection Server - Add new handles for specified messages
2899
2900
2901in the function above the argument @code{run} is used to initiate
2902transport service,and defined like this:
2903
2904@example
2905static void run (void *cls,
2906struct GNUNET_SERVER_Handle *serv,
2907const struct GNUNET_CONFIGURATION_Handle *cfg) @{
2908 GNUNET_SERVER_add_handlers (serv, handlers); @}
2909@end example
2910
2911
2912Here, @code{GNUNET_SERVER_add_handlers} must be called in the run
2913function to add new handlers in the service. The parameter
2914@code{handlers} is a list of @code{struct GNUNET_SERVER_MessageHandler}
2915to tell the service which function should be called when a particular
2916type of message is received, and should be defined in this way:
2917
2918@example
2919static struct GNUNET_SERVER_MessageHandler handlers[] = @{
2920 @{&handle_start,
2921 NULL,
2922 GNUNET_MESSAGE_TYPE_TRANSPORT_START,
2923 0@},
2924 @{&handle_send,
2925 NULL,
2926 GNUNET_MESSAGE_TYPE_TRANSPORT_SEND,
2927 0@},
2928 @{&handle_try_connect,
2929 NULL,
2930 GNUNET_MESSAGE_TYPE_TRANSPORT_TRY_CONNECT,
2931 sizeof (struct TryConnectMessage)
2932 @},
2933 @{&handle_address_lookup,
2934 NULL,
2935 GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_LOOKUP,
2936 0@},
2937 @{NULL,
2938 NULL,
2939 0,
2940 0@}
2941@};
2942@end example
2943
2944
2945As shown, the first member of the struct in the first area is a callback
2946function, which is called to process the specified message types, given
2947as the third member. The second parameter is the closure for the callback
2948function, which is set to @code{NULL} in most cases, and the last
2949parameter is the expected size of the message of this type, usually we
2950set it to 0 to accept variable size, for special cases the exact size of
2951the specified message also can be set. In addition, the terminator sign
2952depicted as @code{@{NULL, NULL, 0, 0@}} is set in the last area.
2953
2954@c ***********************************************************************
2955@node Server - Process request message
2956@subsubsection Server - Process request message
2957
2958
2959After the initialization of transport service, the request message would
2960be processed. Before handling the main message data, the validity of this
2961message should be checked out, e.g., to check whether the size of message
2962is correct.
2963
2964@example
2965size = ntohs (message->size);
2966if (size < sizeof (struct AddressLookupMessage)) @{
2967 GNUNET_break_op (0);
2968 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2969 return; @}
2970@end example
2971
2972
2973Note that, opposite to the construction method of the request message in
2974the client, in the server the function @code{nothl} and @code{ntohs}
2975should be employed during the extraction of the data from the message, so
2976that the data in big endian order can be converted back into little
2977endian order. See more in detail please refer to Introduction of
2978Big Endian and Little Endian.
2979
2980Moreover in this example, the name of the transport stored in the message
2981is a 0-terminated string, so we should also check whether the name of the
2982transport in the received message is 0-terminated:
2983
2984@example
2985nameTransport = (const char *) &address[addressLen];
2986if (nameTransport[size - sizeof
2987 (struct AddressLookupMessage)
2988 - addressLen - 1] != '\0') @{
2989 GNUNET_break_op (0);
2990 GNUNET_SERVER_receive_done (client,
2991 GNUNET_SYSERR);
2992 return; @}
2993@end example
2994
2995Here, @code{GNUNET_SERVER_receive_done} should be called to tell the
2996service that the request is done and can receive the next message. The
2997argument @code{GNUNET_SYSERR} here indicates that the service didn't
2998understand the request message, and the processing of this request would
2999be terminated.
3000
3001In comparison to the aforementioned situation, when the argument is equal
3002to @code{GNUNET_OK}, the service would continue to process the request
3003message.
3004
3005@c ***********************************************************************
3006@node Server - Response to client
3007@subsubsection Server - Response to client
3008
3009
3010Once the processing of current request is done, the server should give the
3011response to the client. A new @code{struct AddressLookupMessage} would be
3012produced by the server in a similar way as the client did and sent to the
3013client, but here the type should be
3014@code{GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_REPLY} rather than
3015@code{GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_LOOKUP} in client.
3016@example
3017struct AddressLookupMessage *msg;
3018size_t len = sizeof (struct AddressLookupMessage)
3019 + addressLen
3020 + strlen (nameTrans) + 1;
3021msg->header->size = htons (len);
3022msg->header->type = htons
3023 (GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_REPLY);
3024
3025// ...
3026
3027struct GNUNET_SERVER_TransmitContext *tc;
3028tc = GNUNET_SERVER_transmit_context_create (client);
3029GNUNET_SERVER_transmit_context_append_data
3030(tc,
3031 NULL,
3032 0,
3033 GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_REPLY);
3034GNUNET_SERVER_transmit_context_run (tc, rtimeout);
3035@end example
3036
3037
3038Note that, there are also a number of other APIs provided to the service
3039to send the message.
3040
3041@c ***********************************************************************
3042@node Server - Notification of clients
3043@subsubsection Server - Notification of clients
3044
3045
3046Often a service needs to (repeatedly) transmit notifications to a client
3047or a group of clients. In these cases, the client typically has once
3048registered for a set of events and then needs to receive a message
3049whenever such an event happens (until the client disconnects). The use of
3050a notification context can help manage message queues to clients and
3051handle disconnects. Notification contexts can be used to send
3052individualized messages to a particular client or to broadcast messages
3053to a group of clients. An individualized notification might look like
3054this:
3055
3056@example
3057GNUNET_SERVER_notification_context_unicast(nc,
3058 client,
3059 msg,
3060 GNUNET_YES);
3061@end example
3062
3063
3064Note that after processing the original registration message for
3065notifications, the server code still typically needs to call
3066@code{GNUNET_SERVER_receive_done} so that the client can transmit further
3067messages to the server.
3068
3069@c ***********************************************************************
3070@node Conversion between Network Byte Order (Big Endian) and Host Byte Order
3071@subsubsection Conversion between Network Byte Order (Big Endian) and Host Byte Order
3072@c %** subsub? it's a referenced page on the ipc document.
3073
3074
3075Here we can simply comprehend big endian and little endian as Network Byte
3076Order and Host Byte Order respectively. What is the difference between
3077both two?
3078
3079Usually in our host computer we store the data byte as Host Byte Order,
3080for example, we store a integer in the RAM which might occupies 4 Byte,
3081as Host Byte Order the higher Byte would be stored at the lower address
3082of RAM, and the lower Byte would be stored at the higher address of RAM.
3083However, contrast to this, Network Byte Order just take the totally
3084opposite way to store the data, says, it will store the lower Byte at the
3085lower address, and the higher Byte will stay at higher address.
3086
3087For the current communication of network, we normally exchange the
3088information by surveying the data package, every two host wants to
3089communicate with each other must send and receive data package through
3090network. In order to maintain the identity of data through the
3091transmission in the network, the order of the Byte storage must changed
3092before sending and after receiving the data.
3093
3094There ten convenient functions to realize the conversion of Byte Order in
3095GNUnet, as following:
3096
3097@table @asis
3098
3099@item uint16_t htons(uint16_t hostshort) Convert host byte order to net
3100byte order with short int
3101@item uint32_t htonl(uint32_t hostlong) Convert host byte
3102order to net byte order with long int
3103@item uint16_t ntohs(uint16_t netshort)
3104Convert net byte order to host byte order with short int
3105@item uint32_t
3106ntohl(uint32_t netlong) Convert net byte order to host byte order with
3107long int
3108@item unsigned long long GNUNET_ntohll (unsigned long long netlonglong)
3109Convert net byte order to host byte order with long long int
3110@item unsigned long long GNUNET_htonll (unsigned long long hostlonglong)
3111Convert host byte order to net byte order with long long int
3112@item struct GNUNET_TIME_RelativeNBO GNUNET_TIME_relative_hton
3113(struct GNUNET_TIME_Relative a) Convert relative time to network byte
3114order.
3115@item struct GNUNET_TIME_Relative GNUNET_TIME_relative_ntoh
3116(struct GNUNET_TIME_RelativeNBO a) Convert relative time from network
3117byte order.
3118@item struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton
3119(struct GNUNET_TIME_Absolute a) Convert relative time to network byte
3120order.
3121@item struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh
3122(struct GNUNET_TIME_AbsoluteNBO a) Convert relative time from network
3123byte order.
3124@end table
3125
3126@cindex Cryptography API
3127@node Cryptography API
3128@subsection Cryptography API
3129
3130
3131The gnunetutil APIs provides the cryptographic primitives used in GNUnet.
3132GNUnet uses 2048 bit RSA keys for the session key exchange and for signing
3133messages by peers and most other public-key operations. Most researchers
3134in cryptography consider 2048 bit RSA keys as secure and practically
3135unbreakable for a long time. The API provides functions to create a fresh
3136key pair, read a private key from a file (or create a new file if the
3137file does not exist), encrypt, decrypt, sign, verify and extraction of
3138the public key into a format suitable for network transmission.
3139
3140For the encryption of files and the actual data exchanged between peers
3141GNUnet uses 256-bit AES encryption. Fresh, session keys are negotiated
3142for every new connection.@ Again, there is no published technique to
3143break this cipher in any realistic amount of time. The API provides
3144functions for generation of keys, validation of keys (important for
3145checking that decryptions using RSA succeeded), encryption and decryption.
3146
3147GNUnet uses SHA-512 for computing one-way hash codes. The API provides
3148functions to compute a hash over a block in memory or over a file on disk.
3149
3150The crypto API also provides functions for randomizing a block of memory,
3151obtaining a single random number and for generating a permutation of the
3152numbers 0 to n-1. Random number generation distinguishes between WEAK and
3153STRONG random number quality; WEAK random numbers are pseudo-random
3154whereas STRONG random numbers use entropy gathered from the operating
3155system.
3156
3157Finally, the crypto API provides a means to deterministically generate a
31581024-bit RSA key from a hash code. These functions should most likely not
3159be used by most applications; most importantly,
3160GNUNET_CRYPTO_rsa_key_create_from_hash does not create an RSA-key that
3161should be considered secure for traditional applications of RSA.
3162
3163@cindex Message Queue API
3164@node Message Queue API
3165@subsection Message Queue API
3166
3167
3168@strong{ Introduction }@
3169Often, applications need to queue messages that
3170are to be sent to other GNUnet peers, clients or services. As all of
3171GNUnet's message-based communication APIs, by design, do not allow
3172messages to be queued, it is common to implement custom message queues
3173manually when they are needed. However, writing very similar code in
3174multiple places is tedious and leads to code duplication.
3175
3176MQ (for Message Queue) is an API that provides the functionality to
3177implement and use message queues. We intend to eventually replace all of
3178the custom message queue implementations in GNUnet with MQ.
3179
3180@strong{ Basic Concepts }@
3181The two most important entities in MQ are queues and envelopes.
3182
3183Every queue is backed by a specific implementation (e.g. for mesh, stream,
3184connection, server client, etc.) that will actually deliver the queued
3185messages. For convenience,@ some queues also allow to specify a list of
3186message handlers. The message queue will then also wait for incoming
3187messages and dispatch them appropriately.
3188
3189An envelope holds the memory for a message, as well as metadata
3190(Where is the envelope queued? What should happen after it has been
3191sent?). Any envelope can only be queued in one message queue.
3192
3193@strong{ Creating Queues }@
3194The following is a list of currently available message queues. Note that
3195to avoid layering issues, message queues for higher level APIs are not
3196part of @code{libgnunetutil}, but@ the respective API itself provides the
3197queue implementation.
3198
3199@table @asis
3200
3201@item @code{GNUNET_MQ_queue_for_connection_client}
3202Transmits queued messages over a @code{GNUNET_CLIENT_Connection} handle.
3203Also supports receiving with message handlers.
3204
3205@item @code{GNUNET_MQ_queue_for_server_client}
3206Transmits queued messages over a @code{GNUNET_SERVER_Client} handle. Does
3207not support incoming message handlers.
3208
3209@item @code{GNUNET_MESH_mq_create} Transmits queued messages over a
3210@code{GNUNET_MESH_Tunnel} handle. Does not support incoming message
3211handlers.
3212
3213@item @code{GNUNET_MQ_queue_for_callbacks} This is the most general
3214implementation. Instead of delivering and receiving messages with one of
3215GNUnet's communication APIs, implementation callbacks are called. Refer to
3216"Implementing Queues" for a more detailed explanation.
3217@end table
3218
3219
3220@strong{ Allocating Envelopes }@
3221A GNUnet message (as defined by the GNUNET_MessageHeader) has three
3222parts: The size, the type, and the body.
3223
3224MQ provides macros to allocate an envelope containing a message
3225conveniently, automatically setting the size and type fields of the
3226message.
3227
3228Consider the following simple message, with the body consisting of a
3229single number value.
3230@c why the empty code function?
3231@code{}
3232
3233@example
3234struct NumberMessage @{
3235 /** Type: GNUNET_MESSAGE_TYPE_EXAMPLE_1 */
3236 struct GNUNET_MessageHeader header;
3237 uint32_t number GNUNET_PACKED;
3238@};
3239@end example
3240
3241An envelope containing an instance of the NumberMessage can be
3242constructed like this:
3243
3244@example
3245struct GNUNET_MQ_Envelope *ev;
3246struct NumberMessage *msg;
3247ev = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_EXAMPLE_1);
3248msg->number = htonl (42);
3249@end example
3250
3251In the above code, @code{GNUNET_MQ_msg} is a macro. The return value is
3252the newly allocated envelope. The first argument must be a pointer to some
3253@code{struct} containing a @code{struct GNUNET_MessageHeader header}
3254field, while the second argument is the desired message type, in host
3255byte order.
3256
3257The @code{msg} pointer now points to an allocated message, where the
3258message type and the message size are already set. The message's size is
3259inferred from the type of the @code{msg} pointer: It will be set to
3260'sizeof(*msg)', properly converted to network byte order.
3261
3262If the message body's size is dynamic, then the macro
3263@code{GNUNET_MQ_msg_extra} can be used to allocate an envelope whose
3264message has additional space allocated after the @code{msg} structure.
3265
3266If no structure has been defined for the message,
3267@code{GNUNET_MQ_msg_header_extra} can be used to allocate additional space
3268after the message header. The first argument then must be a pointer to a
3269@code{GNUNET_MessageHeader}.
3270
3271@strong{Envelope Properties}@
3272A few functions in MQ allow to set additional properties on envelopes:
3273
3274@table @asis
3275
3276@item @code{GNUNET_MQ_notify_sent} Allows to specify a function that will
3277be called once the envelope's message has been sent irrevocably.
3278An envelope can be canceled precisely up to the@ point where the notify
3279sent callback has been called.
3280
3281@item @code{GNUNET_MQ_disable_corking} No corking will be used when
3282sending the message. Not every@ queue supports this flag, per default,
3283envelopes are sent with corking.@
3284
3285@end table
3286
3287
3288@strong{Sending Envelopes}@
3289Once an envelope has been constructed, it can be queued for sending with
3290@code{GNUNET_MQ_send}.
3291
3292Note that in order to avoid memory leaks, an envelope must either be sent
3293(the queue will free it) or destroyed explicitly with
3294@code{GNUNET_MQ_discard}.
3295
3296@strong{Canceling Envelopes}@
3297An envelope queued with @code{GNUNET_MQ_send} can be canceled with
3298@code{GNUNET_MQ_cancel}. Note that after the notify sent callback has
3299been called, canceling a message results in undefined behavior.
3300Thus it is unsafe to cancel an envelope that does not have a notify sent
3301callback. When canceling an envelope, it is not necessary@ to call
3302@code{GNUNET_MQ_discard}, and the envelope can't be sent again.
3303
3304@strong{ Implementing Queues }@
3305@code{TODO}
3306
3307@cindex Service API
3308@node Service API
3309@subsection Service API
3310
3311
3312Most GNUnet code lives in the form of services. Services are processes
3313that offer an API for other components of the system to build on. Those
3314other components can be command-line tools for users, graphical user
3315interfaces or other services. Services provide their API using an IPC
3316protocol. For this, each service must listen on either a TCP port or a
3317UNIX domain socket; for this, the service implementation uses the server
3318API. This use of server is exposed directly to the users of the service
3319API. Thus, when using the service API, one is usually also often using
3320large parts of the server API. The service API provides various
3321convenience functions, such as parsing command-line arguments and the
3322configuration file, which are not found in the server API.
3323The dual to the service/server API is the client API, which can be used to
3324access services.
3325
3326The most common way to start a service is to use the
3327@code{GNUNET_SERVICE_run} function from the program's main function.
3328@code{GNUNET_SERVICE_run} will then parse the command line and
3329configuration files and, based on the options found there,
3330start the server. It will then give back control to the main
3331program, passing the server and the configuration to the
3332@code{GNUNET_SERVICE_Main} callback. @code{GNUNET_SERVICE_run}
3333will also take care of starting the scheduler loop.
3334If this is inappropriate (for example, because the scheduler loop
3335is already running), @code{GNUNET_SERVICE_start} and
3336related functions provide an alternative to @code{GNUNET_SERVICE_run}.
3337
3338When starting a service, the service_name option is used to determine
3339which sections in the configuration file should be used to configure the
3340service. A typical value here is the name of the @file{src/}
3341sub-directory, for example @file{statistics}.
3342The same string would also be given to
3343@code{GNUNET_CLIENT_connect} to access the service.
3344
3345Once a service has been initialized, the program should use the
3346@code{GNUNET_SERVICE_Main} callback to register message handlers
3347using @code{GNUNET_SERVER_add_handlers}.
3348The service will already have registered a handler for the
3349"TEST" message.
3350
3351@findex GNUNET_SERVICE_Options
3352The option bitfield (@code{enum GNUNET_SERVICE_Options})
3353determines how a service should behave during shutdown.
3354There are three key strategies:
3355
3356@table @asis
3357
3358@item instant (@code{GNUNET_SERVICE_OPTION_NONE})
3359Upon receiving the shutdown
3360signal from the scheduler, the service immediately terminates the server,
3361closing all existing connections with clients.
3362@item manual (@code{GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN})
3363The service does nothing by itself
3364during shutdown. The main program will need to take the appropriate
3365action by calling GNUNET_SERVER_destroy or GNUNET_SERVICE_stop (depending
3366on how the service was initialized) to terminate the service. This method
3367is used by gnunet-service-arm and rather uncommon.
3368@item soft (@code{GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN})
3369Upon receiving the shutdown signal from the scheduler,
3370the service immediately tells the server to stop
3371listening for incoming clients. Requests from normal existing clients are
3372still processed and the server/service terminates once all normal clients
3373have disconnected. Clients that are not expected to ever disconnect (such
3374as clients that monitor performance values) can be marked as 'monitor'
3375clients using GNUNET_SERVER_client_mark_monitor. Those clients will
3376continue to be processed until all 'normal' clients have disconnected.
3377Then, the server will terminate, closing the monitor connections.
3378This mode is for example used by 'statistics', allowing existing 'normal'
3379clients to set (possibly persistent) statistic values before terminating.
3380
3381@end table
3382
3383@c ***********************************************************************
3384@node Optimizing Memory Consumption of GNUnet's (Multi-) Hash Maps
3385@subsection Optimizing Memory Consumption of GNUnet's (Multi-) Hash Maps
3386
3387
3388A commonly used data structure in GNUnet is a (multi-)hash map. It is most
3389often used to map a peer identity to some data structure, but also to map
3390arbitrary keys to values (for example to track requests in the distributed
3391hash table or in file-sharing). As it is commonly used, the DHT is
3392actually sometimes responsible for a large share of GNUnet's overall
3393memory consumption (for some processes, 30% is not uncommon). The
3394following text documents some API quirks (and their implications for
3395applications) that were recently introduced to minimize the footprint of
3396the hash map.
3397
3398
3399@c ***********************************************************************
3400@menu
3401* Analysis::
3402* Solution::
3403* Migration::
3404* Conclusion::
3405* Availability::
3406@end menu
3407
3408@node Analysis
3409@subsubsection Analysis
3410
3411
3412The main reason for the "excessive" memory consumption by the hash map is
3413that GNUnet uses 512-bit cryptographic hash codes --- and the
3414(multi-)hash map also uses the same 512-bit 'struct GNUNET_HashCode'. As
3415a result, storing just the keys requires 64 bytes of memory for each key.
3416As some applications like to keep a large number of entries in the hash
3417map (after all, that's what maps are good for), 64 bytes per hash is
3418significant: keeping a pointer to the value and having a linked list for
3419collisions consume between 8 and 16 bytes, and 'malloc' may add about the
3420same overhead per allocation, putting us in the 16 to 32 byte per entry
3421ballpark. Adding a 64-byte key then triples the overall memory
3422requirement for the hash map.
3423
3424To make things "worse", most of the time storing the key in the hash map
3425is not required: it is typically already in memory elsewhere! In most
3426cases, the values stored in the hash map are some application-specific
3427struct that _also_ contains the hash. Here is a simplified example:
3428
3429@example
3430struct MyValue @{
3431struct GNUNET_HashCode key;
3432unsigned int my_data; @};
3433
3434// ...
3435val = GNUNET_malloc (sizeof (struct MyValue));
3436val->key = key;
3437val->my_data = 42;
3438GNUNET_CONTAINER_multihashmap_put (map, &key, val, ...);
3439@end example
3440
3441This is a common pattern as later the entries might need to be removed,
3442and at that time it is convenient to have the key immediately at hand:
3443
3444@example
3445GNUNET_CONTAINER_multihashmap_remove (map, &val->key, val);
3446@end example
3447
3448
3449Note that here we end up with two times 64 bytes for the key, plus maybe
345064 bytes total for the rest of the 'struct MyValue' and the map entry in
3451the hash map. The resulting redundant storage of the key increases
3452overall memory consumption per entry from the "optimal" 128 bytes to 192
3453bytes. This is not just an extreme example: overheads in practice are
3454actually sometimes close to those highlighted in this example. This is
3455especially true for maps with a significant number of entries, as there
3456we tend to really try to keep the entries small.
3457
3458@c ***********************************************************************
3459@node Solution
3460@subsubsection Solution
3461
3462
3463The solution that has now been implemented is to @strong{optionally}
3464allow the hash map to not make a (deep) copy of the hash but instead have
3465a pointer to the hash/key in the entry. This reduces the memory
3466consumption for the key from 64 bytes to 4 to 8 bytes. However, it can
3467also only work if the key is actually stored in the entry (which is the
3468case most of the time) and if the entry does not modify the key (which in
3469all of the code I'm aware of has been always the case if there key is
3470stored in the entry). Finally, when the client stores an entry in the
3471hash map, it @strong{must} provide a pointer to the key within the entry,
3472not just a pointer to a transient location of the key. If
3473the client code does not meet these requirements, the result is a dangling
3474pointer and undefined behavior of the (multi-)hash map API.
3475
3476@c ***********************************************************************
3477@node Migration
3478@subsubsection Migration
3479
3480
3481To use the new feature, first check that the values contain the respective
3482key (and never modify it). Then, all calls to
3483@code{GNUNET_CONTAINER_multihashmap_put} on the respective map must be
3484audited and most likely changed to pass a pointer into the value's struct.
3485For the initial example, the new code would look like this:
3486
3487@example
3488struct MyValue @{
3489struct GNUNET_HashCode key;
3490unsigned int my_data; @};
3491
3492// ...
3493val = GNUNET_malloc (sizeof (struct MyValue));
3494val->key = key; val->my_data = 42;
3495GNUNET_CONTAINER_multihashmap_put (map, &val->key, val, ...);
3496@end example
3497
3498
3499Note that @code{&val} was changed to @code{&val->key} in the argument to
3500the @code{put} call. This is critical as often @code{key} is on the stack
3501or in some other transient data structure and thus having the hash map
3502keep a pointer to @code{key} would not work. Only the key inside of
3503@code{val} has the same lifetime as the entry in the map (this must of
3504course be checked as well). Naturally, @code{val->key} must be
3505initialized before the @code{put} call. Once all @code{put} calls have
3506been converted and double-checked, you can change the call to create the
3507hash map from
3508
3509@example
3510map =
3511GNUNET_CONTAINER_multihashmap_create (SIZE, GNUNET_NO);
3512@end example
3513
3514to
3515
3516@example
3517map = GNUNET_CONTAINER_multihashmap_create (SIZE, GNUNET_YES);
3518@end example
3519
3520If everything was done correctly, you now use about 60 bytes less memory
3521per entry in @code{map}. However, if now (or in the future) any call to
3522@code{put} does not ensure that the given key is valid until the entry is
3523removed from the map, undefined behavior is likely to be observed.
3524
3525@c ***********************************************************************
3526@node Conclusion
3527@subsubsection Conclusion
3528
3529
3530The new optimization can is often applicable and can result in a
3531reduction in memory consumption of up to 30% in practice. However, it
3532makes the code less robust as additional invariants are imposed on the
3533multi hash map client. Thus applications should refrain from enabling the
3534new mode unless the resulting performance increase is deemed significant
3535enough. In particular, it should generally not be used in new code (wait
3536at least until benchmarks exist).
3537
3538@c ***********************************************************************
3539@node Availability
3540@subsubsection Availability
3541
3542
3543The new multi hash map code was committed in SVN 24319 (which made its
3544way into GNUnet version 0.9.4).
3545Various subsystems (transport, core, dht, file-sharing) were
3546previously audited and modified to take advantage of the new capability.
3547In particular, memory consumption of the file-sharing service is expected
3548to drop by 20-30% due to this change.
3549
3550
3551@cindex CONTAINER_MDLL API
3552@node CONTAINER_MDLL API
3553@subsection CONTAINER_MDLL API
3554
3555
3556This text documents the GNUNET_CONTAINER_MDLL API. The
3557GNUNET_CONTAINER_MDLL API is similar to the GNUNET_CONTAINER_DLL API in
3558that it provides operations for the construction and manipulation of
3559doubly-linked lists. The key difference to the (simpler) DLL-API is that
3560the MDLL-version allows a single element (instance of a "struct") to be
3561in multiple linked lists at the same time.
3562
3563Like the DLL API, the MDLL API stores (most of) the data structures for
3564the doubly-linked list with the respective elements; only the 'head' and
3565'tail' pointers are stored "elsewhere" --- and the application needs to
3566provide the locations of head and tail to each of the calls in the
3567MDLL API. The key difference for the MDLL API is that the "next" and
3568"previous" pointers in the struct can no longer be simply called "next"
3569and "prev" --- after all, the element may be in multiple doubly-linked
3570lists, so we cannot just have one "next" and one "prev" pointer!
3571
3572The solution is to have multiple fields that must have a name of the
3573format "next_XX" and "prev_XX" where "XX" is the name of one of the
3574doubly-linked lists. Here is a simple example:
3575
3576@example
3577struct MyMultiListElement @{
3578 struct MyMultiListElement *next_ALIST;
3579 struct MyMultiListElement *prev_ALIST;
3580 struct MyMultiListElement *next_BLIST;
3581 struct MyMultiListElement *prev_BLIST;
3582 void
3583 *data;
3584@};
3585@end example
3586
3587
3588Note that by convention, we use all-uppercase letters for the list names.
3589In addition, the program needs to have a location for the head and tail
3590pointers for both lists, for example:
3591
3592@example
3593static struct MyMultiListElement *head_ALIST;
3594static struct MyMultiListElement *tail_ALIST;
3595static struct MyMultiListElement *head_BLIST;
3596static struct MyMultiListElement *tail_BLIST;
3597@end example
3598
3599
3600Using the MDLL-macros, we can now insert an element into the ALIST:
3601
3602@example
3603GNUNET_CONTAINER_MDLL_insert (ALIST, head_ALIST, tail_ALIST, element);
3604@end example
3605
3606
3607Passing "ALIST" as the first argument to MDLL specifies which of the
3608next/prev fields in the 'struct MyMultiListElement' should be used. The
3609extra "ALIST" argument and the "_ALIST" in the names of the
3610next/prev-members are the only differences between the MDDL and DLL-API.
3611Like the DLL-API, the MDLL-API offers functions for inserting (at head,
3612at tail, after a given element) and removing elements from the list.
3613Iterating over the list should be done by directly accessing the
3614"next_XX" and/or "prev_XX" members.
3615
3616@cindex Automatic Restart Manager
3617@cindex ARM
3618@node Automatic Restart Manager (ARM)
3619@section Automatic Restart Manager (ARM)
3620
3621
3622GNUnet's Automated Restart Manager (ARM) is the GNUnet service responsible
3623for system initialization and service babysitting. ARM starts and halts
3624services, detects configuration changes and restarts services impacted by
3625the changes as needed. It's also responsible for restarting services in
3626case of crashes and is planned to incorporate automatic debugging for
3627diagnosing service crashes providing developers insights about crash
3628reasons. The purpose of this document is to give GNUnet developer an idea
3629about how ARM works and how to interact with it.
3630
3631@menu
3632* Basic functionality::
3633* Key configuration options::
3634* ARM - Availability::
3635* Reliability::
3636@end menu
3637
3638@c ***********************************************************************
3639@node Basic functionality
3640@subsection Basic functionality
3641
3642
3643@itemize @bullet
3644@item ARM source code can be found under "src/arm".@ Service processes are
3645managed by the functions in "gnunet-service-arm.c" which is controlled
3646with "gnunet-arm.c" (main function in that file is ARM's entry point).
3647
3648@item The functions responsible for communicating with ARM , starting and
3649stopping services -including ARM service itself- are provided by the
3650ARM API "arm_api.c".@ Function: GNUNET_ARM_connect() returns to the caller
3651an ARM handle after setting it to the caller's context (configuration and
3652scheduler in use). This handle can be used afterwards by the caller to
3653communicate with ARM. Functions GNUNET_ARM_start_service() and
3654GNUNET_ARM_stop_service() are used for starting and stopping services
3655respectively.
3656
3657@item A typical example of using these basic ARM services can be found in
3658file test_arm_api.c. The test case connects to ARM, starts it, then uses
3659it to start a service "resolver", stops the "resolver" then stops "ARM".
3660@end itemize
3661
3662@c ***********************************************************************
3663@node Key configuration options
3664@subsection Key configuration options
3665
3666
3667Configurations for ARM and services should be available in a .conf file
3668(As an example, see test_arm_api_data.conf). When running ARM, the
3669configuration file to use should be passed to the command:
3670
3671@example
3672$ gnunet-arm -s -c configuration_to_use.conf
3673@end example
3674
3675If no configuration is passed, the default configuration file will be used
3676(see GNUNET_PREFIX/share/gnunet/defaults.conf which is created from
3677contrib/defaults.conf).@ Each of the services is having a section starting
3678by the service name between square brackets, for example: "[arm]".
3679The following options configure how ARM configures or interacts with the
3680various services:
3681
3682@table @asis
3683
3684@item PORT Port number on which the service is listening for incoming TCP
3685connections. ARM will start the services should it notice a request at
3686this port.
3687
3688@item HOSTNAME Specifies on which host the service is deployed. Note
3689that ARM can only start services that are running on the local system
3690(but will not check that the hostname matches the local machine name).
3691This option is used by the @code{gnunet_client_lib.h} implementation to
3692determine which system to connect to. The default is "localhost".
3693
3694@item BINARY The name of the service binary file.
3695
3696@item OPTIONS To be passed to the service.
3697
3698@item PREFIX A command to pre-pend to the actual command, for example,
3699running a service with "valgrind" or "gdb"
3700
3701@item DEBUG Run in debug mode (much verbosity).
3702
3703@item START_ON_DEMAND ARM will listen to UNIX domain socket and/or TCP port of
3704the service and start the service on-demand.
3705
3706@item IMMEDIATE_START ARM will always start this service when the peer
3707is started.
3708
3709@item ACCEPT_FROM IPv4 addresses the service accepts connections from.
3710
3711@item ACCEPT_FROM6 IPv6 addresses the service accepts connections from.
3712
3713@end table
3714
3715
3716Options that impact the operation of ARM overall are in the "[arm]"
3717section. ARM is a normal service and has (except for START_ON_DEMAND) all of the
3718options that other services do. In addition, ARM has the
3719following options:
3720
3721@table @asis
3722
3723@item GLOBAL_PREFIX Command to be pre-pended to all services that are
3724going to run.
3725
3726@item GLOBAL_POSTFIX Global option that will be supplied to all the
3727services that are going to run.
3728
3729@end table
3730
3731@c ***********************************************************************
3732@node ARM - Availability
3733@subsection ARM - Availability
3734
3735
3736As mentioned before, one of the features provided by ARM is starting
3737services on demand. Consider the example of one service "client" that
3738wants to connect to another service a "server". The "client" will ask ARM
3739to run the "server". ARM starts the "server". The "server" starts
3740listening to incoming connections. The "client" will establish a
3741connection with the "server". And then, they will start to communicate
3742together.@ One problem with that scheme is that it's slow!@
3743The "client" service wants to communicate with the "server" service at
3744once and is not willing wait for it to be started and listening to
3745incoming connections before serving its request.@ One solution for that
3746problem will be that ARM starts all services as default services. That
3747solution will solve the problem, yet, it's not quite practical, for some
3748services that are going to be started can never be used or are going to
3749be used after a relatively long time.@
3750The approach followed by ARM to solve this problem is as follows:
3751
3752@itemize @bullet
3753
3754@item For each service having a PORT field in the configuration file and
3755that is not one of the default services ( a service that accepts incoming
3756connections from clients), ARM creates listening sockets for all addresses
3757associated with that service.
3758
3759@item The "client" will immediately establish a connection with
3760the "server".
3761
3762@item ARM --- pretending to be the "server" --- will listen on the
3763respective port and notice the incoming connection from the "client"
3764(but not accept it), instead
3765
3766@item Once there is an incoming connection, ARM will start the "server",
3767passing on the listen sockets (now, the service is started and can do its
3768work).
3769
3770@item Other client services now can directly connect directly to the
3771"server".
3772
3773@end itemize
3774
3775@c ***********************************************************************
3776@node Reliability
3777@subsection Reliability
3778
3779One of the features provided by ARM, is the automatic restart of crashed
3780services.@ ARM needs to know which of the running services died. Function
3781"gnunet-service-arm.c/maint_child_death()" is responsible for that. The
3782function is scheduled to run upon receiving a SIGCHLD signal. The
3783function, then, iterates ARM's list of services running and monitors
3784which service has died (crashed). For all crashing services, ARM restarts
3785them.@
3786Now, considering the case of a service having a serious problem causing it
3787to crash each time it's started by ARM. If ARM keeps blindly restarting
3788such a service, we are going to have the pattern:
3789start-crash-restart-crash-restart-crash and so forth!! Which is of course
3790not practical.@
3791For that reason, ARM schedules the service to be restarted after waiting
3792for some delay that grows exponentially with each crash/restart of that
3793service.@ To clarify the idea, considering the following example:
3794
3795@itemize @bullet
3796
3797@item Service S crashed.
3798
3799@item ARM receives the SIGCHLD and inspects its list of services to find
3800the dead one(s).
3801
3802@item ARM finds S dead and schedules it for restarting after "backoff"
3803time which is initially set to 1ms. ARM will double the backoff time
3804correspondent to S (now backoff(S) = 2ms)
3805
3806@item Because there is a severe problem with S, it crashed again.
3807
3808@item Again ARM receives the SIGCHLD and detects that it's S again that's
3809crashed. ARM schedules it for restarting but after its new backoff time
3810(which became 2ms), and doubles its backoff time (now backoff(S) = 4).
3811
3812@item and so on, until backoff(S) reaches a certain threshold
3813(@code{EXPONENTIAL_BACKOFF_THRESHOLD} is set to half an hour),
3814after reaching it, backoff(S) will remain half an hour,
3815hence ARM won't be busy for a lot of time trying to restart a
3816problematic service.
3817@end itemize
3818
3819@cindex TRANSPORT Subsystem
3820@node TRANSPORT Subsystem
3821@section TRANSPORT Subsystem
3822
3823
3824This chapter documents how the GNUnet transport subsystem works. The
3825GNUnet transport subsystem consists of three main components: the
3826transport API (the interface used by the rest of the system to access the
3827transport service), the transport service itself (most of the interesting
3828functions, such as choosing transports, happens here) and the transport
3829plugins. A transport plugin is a concrete implementation for how two
3830GNUnet peers communicate; many plugins exist, for example for
3831communication via TCP, UDP, HTTP, HTTPS and others. Finally, the
3832transport subsystem uses supporting code, especially the NAT/UPnP
3833library to help with tasks such as NAT traversal.
3834
3835Key tasks of the transport service include:
3836
3837@itemize @bullet
3838
3839@item Create our HELLO message, notify clients and neighbours if our HELLO
3840changes (using NAT library as necessary)
3841
3842@item Validate HELLOs from other peers (send PING), allow other peers to
3843validate our HELLO's addresses (send PONG)
3844
3845@item Upon request, establish connections to other peers (using address
3846selection from ATS subsystem) and maintain them (again using PINGs and
3847PONGs) as long as desired
3848
3849@item Accept incoming connections, give ATS service the opportunity to
3850switch communication channels
3851
3852@item Notify clients about peers that have connected to us or that have
3853been disconnected from us
3854
3855@item If a (stateful) connection goes down unexpectedly (without explicit
3856DISCONNECT), quickly attempt to recover (without notifying clients) but do
3857notify clients quickly if reconnecting fails
3858
3859@item Send (payload) messages arriving from clients to other peers via
3860transport plugins and receive messages from other peers, forwarding
3861those to clients
3862
3863@item Enforce inbound traffic limits (using flow-control if it is
3864applicable); outbound traffic limits are enforced by CORE, not by us (!)
3865
3866@item Enforce restrictions on P2P connection as specified by the blacklist
3867configuration and blacklisting clients
3868@end itemize
3869
3870Note that the term "clients" in the list above really refers to the
3871GNUnet-CORE service, as CORE is typically the only client of the
3872transport service.
3873
3874@menu
3875* Address validation protocol::
3876@end menu
3877
3878@node Address validation protocol
3879@subsection Address validation protocol
3880
3881
3882This section documents how the GNUnet transport service validates
3883connections with other peers. It is a high-level description of the
3884protocol necessary to understand the details of the implementation. It
3885should be noted that when we talk about PING and PONG messages in this
3886section, we refer to transport-level PING and PONG messages, which are
3887different from core-level PING and PONG messages (both in implementation
3888and function).
3889
3890The goal of transport-level address validation is to minimize the chances
3891of a successful man-in-the-middle attack against GNUnet peers on the
3892transport level. Such an attack would not allow the adversary to decrypt
3893the P2P transmissions, but a successful attacker could at least measure
3894traffic volumes and latencies (raising the adversaries capabilities by
3895those of a global passive adversary in the worst case). The scenarios we
3896are concerned about is an attacker, Mallory, giving a @code{HELLO} to
3897Alice that claims to be for Bob, but contains Mallory's IP address
3898instead of Bobs (for some transport).
3899Mallory would then forward the traffic to Bob (by initiating a
3900connection to Bob and claiming to be Alice). As a further
3901complication, the scheme has to work even if say Alice is behind a NAT
3902without traversal support and hence has no address of her own (and thus
3903Alice must always initiate the connection to Bob).
3904
3905An additional constraint is that @code{HELLO} messages do not contain a
3906cryptographic signature since other peers must be able to edit
3907(i.e. remove) addresses from the @code{HELLO} at any time (this was
3908not true in GNUnet 0.8.x). A basic @strong{assumption} is that each peer
3909knows the set of possible network addresses that it @strong{might}
3910be reachable under (so for example, the external IP address of the
3911NAT plus the LAN address(es) with the respective ports).
3912
3913The solution is the following. If Alice wants to validate that a given
3914address for Bob is valid (i.e. is actually established @strong{directly}
3915with the intended target), she sends a PING message over that connection
3916to Bob. Note that in this case, Alice initiated the connection so only
3917Alice knows which address was used for sure (Alice may be behind NAT, so
3918whatever address Bob sees may not be an address Alice knows she has).
3919Bob checks that the address given in the @code{PING} is actually one
3920of Bob's addresses (ie: does not belong to Mallory), and if it is,
3921sends back a @code{PONG} (with a signature that says that Bob
3922owns/uses the address from the @code{PING}).
3923Alice checks the signature and is happy if it is valid and the address
3924in the @code{PONG} is the address Alice used.
3925This is similar to the 0.8.x protocol where the @code{HELLO} contained a
3926signature from Bob for each address used by Bob.
3927Here, the purpose code for the signature is
3928@code{GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_OWN}. After this, Alice will
3929remember Bob's address and consider the address valid for a while (12h in
3930the current implementation). Note that after this exchange, Alice only
3931considers Bob's address to be valid, the connection itself is not
3932considered 'established'. In particular, Alice may have many addresses
3933for Bob that Alice considers valid.
3934
3935The @code{PONG} message is protected with a nonce/challenge against replay
3936attacks (@uref{http://en.wikipedia.org/wiki/Replay_attack, replay})
3937and uses an expiration time for the signature (but those are almost
3938implementation details).
3939
3940@cindex NAT library
3941@node NAT library
3942@section NAT library
3943
3944
3945The goal of the GNUnet NAT library is to provide a general-purpose API for
3946NAT traversal @strong{without} third-party support. So protocols that
3947involve contacting a third peer to help establish a connection between
3948two peers are outside of the scope of this API. That does not mean that
3949GNUnet doesn't support involving a third peer (we can do this with the
3950distance-vector transport or using application-level protocols), it just
3951means that the NAT API is not concerned with this possibility. The API is
3952written so that it will work for IPv6-NAT in the future as well as
3953current IPv4-NAT. Furthermore, the NAT API is always used, even for peers
3954that are not behind NAT --- in that case, the mapping provided is simply
3955the identity.
3956
3957NAT traversal is initiated by calling @code{GNUNET_NAT_register}. Given a
3958set of addresses that the peer has locally bound to (TCP or UDP), the NAT
3959library will return (via callback) a (possibly longer) list of addresses
3960the peer @strong{might} be reachable under. Internally, depending on the
3961configuration, the NAT library will try to punch a hole (using UPnP) or
3962just "know" that the NAT was manually punched and generate the respective
3963external IP address (the one that should be globally visible) based on
3964the given information.
3965
3966The NAT library also supports ICMP-based NAT traversal. Here, the other
3967peer can request connection-reversal by this peer (in this special case,
3968the peer is even allowed to configure a port number of zero). If the NAT
3969library detects a connection-reversal request, it returns the respective
3970target address to the client as well. It should be noted that
3971connection-reversal is currently only intended for TCP, so other plugins
3972@strong{must} pass @code{NULL} for the reversal callback. Naturally, the
3973NAT library also supports requesting connection reversal from a remote
3974peer (@code{GNUNET_NAT_run_client}).
3975
3976Once initialized, the NAT handle can be used to test if a given address is
3977possibly a valid address for this peer (@code{GNUNET_NAT_test_address}).
3978This is used for validating our addresses when generating PONGs.
3979
3980Finally, the NAT library contains an API to test if our NAT configuration
3981is correct. Using @code{GNUNET_NAT_test_start} @strong{before} binding to
3982the respective port, the NAT library can be used to test if the
3983configuration works. The test function act as a local client, initialize
3984the NAT traversal and then contact a @code{gnunet-nat-server} (running by
3985default on @code{gnunet.org}) and ask for a connection to be established.
3986This way, it is easy to test if the current NAT configuration is valid.
3987
3988@node Distance-Vector plugin
3989@section Distance-Vector plugin
3990
3991
3992The Distance Vector (DV) transport is a transport mechanism that allows
3993peers to act as relays for each other, thereby connecting peers that would
3994otherwise be unable to connect. This gives a larger connection set to
3995applications that may work better with more peers to choose from (for
3996example, File Sharing and/or DHT).
3997
3998The Distance Vector transport essentially has two functions. The first is
3999"gossiping" connection information about more distant peers to directly
4000connected peers. The second is taking messages intended for non-directly
4001connected peers and encapsulating them in a DV wrapper that contains the
4002required information for routing the message through forwarding peers. Via
4003gossiping, optimal routes through the known DV neighborhood are discovered
4004and utilized and the message encapsulation provides some benefits in
4005addition to simply getting the message from the correct source to the
4006proper destination.
4007
4008The gossiping function of DV provides an up to date routing table of
4009peers that are available up to some number of hops. We call this a
4010fisheye view of the network (like a fish, nearby objects are known while
4011more distant ones unknown). Gossip messages are sent only to directly
4012connected peers, but they are sent about other knowns peers within the
4013"fisheye distance". Whenever two peers connect, they immediately gossip
4014to each other about their appropriate other neighbors. They also gossip
4015about the newly connected peer to previously
4016connected neighbors. In order to keep the routing tables up to date,
4017disconnect notifications are propagated as gossip as well (because
4018disconnects may not be sent/received, timeouts are also used remove
4019stagnant routing table entries).
4020
4021Routing of messages via DV is straightforward. When the DV transport is
4022notified of a message destined for a non-direct neighbor, the appropriate
4023forwarding peer is selected, and the base message is encapsulated in a DV
4024message which contains information about the initial peer and the intended
4025recipient. At each forwarding hop, the initial peer is validated (the
4026forwarding peer ensures that it has the initial peer in its neighborhood,
4027otherwise the message is dropped). Next the base message is
4028re-encapsulated in a new DV message for the next hop in the forwarding
4029chain (or delivered to the current peer, if it has arrived at the
4030destination).
4031
4032Assume a three peer network with peers Alice, Bob and Carol. Assume that
4033
4034@example
4035Alice <-> Bob and Bob <-> Carol
4036@end example
4037
4038@noindent
4039are direct (e.g. over TCP or UDP transports) connections, but that
4040Alice cannot directly connect to Carol.
4041This may be the case due to NAT or firewall restrictions, or perhaps
4042based on one of the peers respective configurations. If the Distance
4043Vector transport is enabled on all three peers, it will automatically
4044discover (from the gossip protocol) that Alice and Carol can connect via
4045Bob and provide a "virtual" Alice <-> Carol connection. Routing between
4046Alice and Carol happens as follows; Alice creates a message destined for
4047Carol and notifies the DV transport about it. The DV transport at Alice
4048looks up Carol in the routing table and finds that the message must be
4049sent through Bob for Carol. The message is encapsulated setting Alice as
4050the initiator and Carol as the destination and sent to Bob. Bob receives
4051the messages, verifies that both Alice and Carol are known to Bob, and
4052re-wraps the message in a new DV message for Carol.
4053The DV transport at Carol receives this message, unwraps the original
4054message, and delivers it to Carol as though it came directly from Alice.
4055
4056@cindex SMTP plugin
4057@node SMTP plugin
4058@section SMTP plugin
4059
4060@c TODO: Update!
4061
4062This section describes the new SMTP transport plugin for GNUnet as it
4063exists in the 0.7.x and 0.8.x branch. SMTP support is currently not
4064available in GNUnet 0.9.x. This page also describes the transport layer
4065abstraction (as it existed in 0.7.x and 0.8.x) in more detail and gives
4066some benchmarking results. The performance results presented are quite
4067old and maybe outdated at this point.
4068For the readers in the year 2019, you will notice by the mention of
4069version 0.7, 0.8, and 0.9 that this section has to be taken with your
4070usual grain of salt and be updated eventually.
4071
4072@itemize @bullet
4073@item Why use SMTP for a peer-to-peer transport?
4074@item SMTPHow does it work?
4075@item How do I configure my peer?
4076@item How do I test if it works?
4077@item How fast is it?
4078@item Is there any additional documentation?
4079@end itemize
4080
4081
4082@menu
4083* Why use SMTP for a peer-to-peer transport?::
4084* How does it work?::
4085* How do I configure my peer?::
4086* How do I test if it works?::
4087* How fast is it?::
4088@end menu
4089
4090@node Why use SMTP for a peer-to-peer transport?
4091@subsection Why use SMTP for a peer-to-peer transport?
4092
4093
4094There are many reasons why one would not want to use SMTP:
4095
4096@itemize @bullet
4097@item SMTP is using more bandwidth than TCP, UDP or HTTP
4098@item SMTP has a much higher latency.
4099@item SMTP requires significantly more computation (encoding and decoding
4100time) for the peers.
4101@item SMTP is significantly more complicated to configure.
4102@item SMTP may be abused by tricking GNUnet into sending mail to@
4103non-participating third parties.
4104@end itemize
4105
4106So why would anybody want to use SMTP?
4107@itemize @bullet
4108@item SMTP can be used to contact peers behind NAT boxes (in virtual
4109private networks).
4110@item SMTP can be used to circumvent policies that limit or prohibit
4111peer-to-peer traffic by masking as "legitimate" traffic.
4112@item SMTP uses E-mail addresses which are independent of a specific IP,
4113which can be useful to address peers that use dynamic IP addresses.
4114@item SMTP can be used to initiate a connection (e.g. initial address
4115exchange) and peers can then negotiate the use of a more efficient
4116protocol (e.g. TCP) for the actual communication.
4117@end itemize
4118
4119In summary, SMTP can for example be used to send a message to a peer
4120behind a NAT box that has a dynamic IP to tell the peer to establish a
4121TCP connection to a peer outside of the private network. Even an
4122extraordinary overhead for this first message would be irrelevant in this
4123type of situation.
4124
4125@node How does it work?
4126@subsection How does it work?
4127
4128
4129When a GNUnet peer needs to send a message to another GNUnet peer that has
4130advertised (only) an SMTP transport address, GNUnet base64-encodes the
4131message and sends it in an E-mail to the advertised address. The
4132advertisement contains a filter which is placed in the E-mail header,
4133such that the receiving host can filter the tagged E-mails and forward it
4134to the GNUnet peer process. The filter can be specified individually by
4135each peer and be changed over time. This makes it impossible to censor
4136GNUnet E-mail messages by searching for a generic filter.
4137
4138@node How do I configure my peer?
4139@subsection How do I configure my peer?
4140
4141
4142First, you need to configure @code{procmail} to filter your inbound E-mail
4143for GNUnet traffic. The GNUnet messages must be delivered into a pipe, for
4144example @code{/tmp/gnunet.smtp}. You also need to define a filter that is
4145used by @command{procmail} to detect GNUnet messages. You are free to
4146choose whichever filter you like, but you should make sure that it does
4147not occur in your other E-mail. In our example, we will use
4148@code{X-mailer: GNUnet}. The @code{~/.procmailrc} configuration file then
4149looks like this:
4150
4151@example
4152:0:
4153* ^X-mailer: GNUnet
4154/tmp/gnunet.smtp
4155# where do you want your other e-mail delivered to
4156# (default: /var/spool/mail/)
4157:0: /var/spool/mail/
4158@end example
4159
4160After adding this file, first make sure that your regular E-mail still
4161works (e.g. by sending an E-mail to yourself). Then edit the GNUnet
4162configuration. In the section @code{SMTP} you need to specify your E-mail
4163address under @code{EMAIL}, your mail server (for outgoing mail) under
4164@code{SERVER}, the filter (X-mailer: GNUnet in the example) under
4165@code{FILTER} and the name of the pipe under @code{PIPE}.@ The completed
4166section could then look like this:
4167
4168@example
4169EMAIL = me@@mail.gnu.org MTU = 65000 SERVER = mail.gnu.org:25 FILTER =
4170"X-mailer: GNUnet" PIPE = /tmp/gnunet.smtp
4171@end example
4172
4173Finally, you need to add @code{smtp} to the list of @code{TRANSPORTS} in
4174the @code{GNUNETD} section. GNUnet peers will use the E-mail address that
4175you specified to contact your peer until the advertisement times out.
4176Thus, if you are not sure if everything works properly or if you are not
4177planning to be online for a long time, you may want to configure this
4178timeout to be short, e.g. just one hour. For this, set
4179@code{HELLOEXPIRES} to @code{1} in the @code{GNUNETD} section.
4180
4181This should be it, but you may probably want to test it first.
4182
4183@node How do I test if it works?
4184@subsection How do I test if it works?
4185
4186
4187Any transport can be subjected to some rudimentary tests using the
4188@code{gnunet-transport-check} tool. The tool sends a message to the local
4189node via the transport and checks that a valid message is received. While
4190this test does not involve other peers and can not check if firewalls or
4191other network obstacles prohibit proper operation, this is a great
4192testcase for the SMTP transport since it tests pretty much nearly all of
4193the functionality.
4194
4195@code{gnunet-transport-check} should only be used without running
4196@code{gnunetd} at the same time. By default, @code{gnunet-transport-check}
4197tests all transports that are specified in the configuration file. But
4198you can specifically test SMTP by giving the option
4199@code{--transport=smtp}.
4200
4201Note that this test always checks if a transport can receive and send.
4202While you can configure most transports to only receive or only send
4203messages, this test will only work if you have configured the transport
4204to send and receive messages.
4205
4206@node How fast is it?
4207@subsection How fast is it?
4208
4209
4210We have measured the performance of the UDP, TCP and SMTP transport layer
4211directly and when used from an application using the GNUnet core.
4212Measuring just the transport layer gives the better view of the actual
4213overhead of the protocol, whereas evaluating the transport from the
4214application puts the overhead into perspective from a practical point of
4215view.
4216
4217The loopback measurements of the SMTP transport were performed on three
4218different machines spanning a range of modern SMTP configurations. We
4219used a PIII-800 running RedHat 7.3 with the Purdue Computer Science
4220configuration which includes filters for spam. We also used a Xenon 2 GHZ
4221with a vanilla RedHat 8.0 sendmail configuration. Furthermore, we used
4222qmail on a PIII-1000 running Sorcerer GNU Linux (SGL). The numbers for
4223UDP and TCP are provided using the SGL configuration. The qmail benchmark
4224uses qmail's internal filtering whereas the sendmail benchmarks relies on
4225procmail to filter and deliver the mail. We used the transport layer to
4226send a message of b bytes (excluding transport protocol headers) directly
4227to the local machine. This way, network latency and packet loss on the
4228wire have no impact on the timings. n messages were sent sequentially over
4229the transport layer, sending message i+1 after the i-th message was
4230received. All messages were sent over the same connection and the time to
4231establish the connection was not taken into account since this overhead is
4232minuscule in practice --- as long as a connection is used for a
4233significant number of messages.
4234
4235@multitable @columnfractions .20 .15 .15 .15 .15 .15
4236@headitem Transport @tab UDP @tab TCP @tab SMTP (Purdue sendmail)
4237@tab SMTP (RH 8.0) @tab SMTP (SGL qmail)
4238@item 11 bytes @tab 31 ms @tab 55 ms @tab 781 s @tab 77 s @tab 24 s
4239@item 407 bytes @tab 37 ms @tab 62 ms @tab 789 s @tab 78 s @tab 25 s
4240@item 1,221 bytes @tab 46 ms @tab 73 ms @tab 804 s @tab 78 s @tab 25 s
4241@end multitable
4242
4243The benchmarks show that UDP and TCP are, as expected, both significantly
4244faster compared with any of the SMTP services. Among the SMTP
4245implementations, there can be significant differences depending on the
4246SMTP configuration. Filtering with an external tool like procmail that
4247needs to re-parse its configuration for each mail can be very expensive.
4248Applying spam filters can also significantly impact the performance of
4249the underlying SMTP implementation. The microbenchmark shows that SMTP
4250can be a viable solution for initiating peer-to-peer sessions: a couple of
4251seconds to connect to a peer are probably not even going to be noticed by
4252users. The next benchmark measures the possible throughput for a
4253transport. Throughput can be measured by sending multiple messages in
4254parallel and measuring packet loss. Note that not only UDP but also the
4255TCP transport can actually loose messages since the TCP implementation
4256drops messages if the @code{write} to the socket would block. While the
4257SMTP protocol never drops messages itself, it is often so
4258slow that only a fraction of the messages can be sent and received in the
4259given time-bounds. For this benchmark we report the message loss after
4260allowing t time for sending m messages. If messages were not sent (or
4261received) after an overall timeout of t, they were considered lost. The
4262benchmark was performed using two Xeon 2 GHZ machines running RedHat 8.0
4263with sendmail. The machines were connected with a direct 100 MBit Ethernet
4264connection.@ Figures udp1200, tcp1200 and smtp-MTUs show that the
4265throughput for messages of size 1,200 octets is 2,343 kbps, 3,310 kbps
4266and 6 kbps for UDP, TCP and SMTP respectively. The high per-message
4267overhead of SMTP can be improved by increasing the MTU, for example, an
4268MTU of 12,000 octets improves the throughput to 13 kbps as figure
4269smtp-MTUs shows. Our research paper) has some more details on the
4270benchmarking results.
4271
4272@cindex Bluetooth plugin
4273@node Bluetooth plugin
4274@section Bluetooth plugin
4275
4276
4277This page describes the new Bluetooth transport plugin for GNUnet. The
4278plugin is still in the testing stage so don't expect it to work
4279perfectly. If you have any questions or problems just post them here or
4280ask on the IRC channel.
4281
4282@itemize @bullet
4283@item What do I need to use the Bluetooth plugin transport?
4284@item BluetoothHow does it work?
4285@item What possible errors should I be aware of?
4286@item How do I configure my peer?
4287@item How can I test it?
4288@end itemize
4289
4290@menu
4291* What do I need to use the Bluetooth plugin transport?::
4292* How does it work2?::
4293* What possible errors should I be aware of?::
4294* How do I configure my peer2?::
4295* How can I test it?::
4296* The implementation of the Bluetooth transport plugin::
4297@end menu
4298
4299@node What do I need to use the Bluetooth plugin transport?
4300@subsection What do I need to use the Bluetooth plugin transport?
4301
4302
4303If you are a GNU/Linux user and you want to use the Bluetooth
4304transport plugin you should install the
4305@command{BlueZ} development libraries (if they aren't already
4306installed).
4307For instructions about how to install the libraries you should
4308check out the BlueZ site
4309(@uref{http://www.bluez.org/, http://www.bluez.org}). If you don't know if
4310you have the necessary libraries, don't worry, just run the GNUnet
4311configure script and you will be able to see a notification at the end
4312which will warn you if you don't have the necessary libraries.
4313
4314@c If you are a Windows user you should have installed the
4315@c @emph{MinGW}/@emph{MSys2} with the latest updates (especially the
4316@c @emph{ws2bth} header). If this is your first build of GNUnet on Windows
4317@c you should check out the SBuild repository. It will semi-automatically
4318@c assembles a @emph{MinGW}/@emph{MSys2} installation with a lot of extra
4319@c packages which are needed for the GNUnet build. So this will ease your
4320@c work!@ Finally you just have to be sure that you have the correct drivers
4321@c for your Bluetooth device installed and that your device is on and in a
4322@c discoverable mode. The Windows Bluetooth Stack supports only the RFCOMM
4323@c protocol so we cannot turn on your device programmatically!
4324
4325@c FIXME: Change to unique title
4326@node How does it work2?
4327@subsection How does it work2?
4328
4329
4330The Bluetooth transport plugin uses virtually the same code as the WLAN
4331plugin and only the helper binary is different. The helper takes a single
4332argument, which represents the interface name and is specified in the
4333configuration file. Here are the basic steps that are followed by the
4334helper binary used on GNU/Linux:
4335
4336@itemize @bullet
4337@item it verifies if the name corresponds to a Bluetooth interface name
4338@item it verifies if the interface is up (if it is not, it tries to bring
4339it up)
4340@item it tries to enable the page and inquiry scan in order to make the
4341device discoverable and to accept incoming connection requests
4342@emph{The above operations require root access so you should start the
4343transport plugin with root privileges.}
4344@item it finds an available port number and registers a SDP service which
4345will be used to find out on which port number is the server listening on
4346and switch the socket in listening mode
4347@item it sends a HELLO message with its address
4348@item finally it forwards traffic from the reading sockets to the STDOUT
4349and from the STDIN to the writing socket
4350@end itemize
4351
4352Once in a while the device will make an inquiry scan to discover the
4353nearby devices and it will send them randomly HELLO messages for peer
4354discovery.
4355
4356@node What possible errors should I be aware of?
4357@subsection What possible errors should I be aware of?
4358
4359
4360@emph{This section is dedicated for GNU/Linux users}
4361
4362Well there are many ways in which things could go wrong but I will try to
4363present some tools that you could use to debug and some scenarios.
4364
4365@itemize @bullet
4366
4367@item @code{bluetoothd -n -d} : use this command to enable logging in the
4368foreground and to print the logging messages
4369
4370@item @code{hciconfig}: can be used to configure the Bluetooth devices.
4371If you run it without any arguments it will print information about the
4372state of the interfaces. So if you receive an error that the device
4373couldn't be brought up you should try to bring it manually and to see if
4374it works (use @code{hciconfig -a hciX up}). If you can't and the
4375Bluetooth address has the form 00:00:00:00:00:00 it means that there is
4376something wrong with the D-Bus daemon or with the Bluetooth daemon. Use
4377@code{bluetoothd} tool to see the logs
4378
4379@item @code{sdptool} can be used to control and interrogate SDP servers.
4380If you encounter problems regarding the SDP server (like the SDP server is
4381down) you should check out if the D-Bus daemon is running correctly and to
4382see if the Bluetooth daemon started correctly(use @code{bluetoothd} tool).
4383Also, sometimes the SDP service could work but somehow the device couldn't
4384register its service. Use @code{sdptool browse [dev-address]} to see if
4385the service is registered. There should be a service with the name of the
4386interface and GNUnet as provider.
4387
4388@item @code{hcitool} : another useful tool which can be used to configure
4389the device and to send some particular commands to it.
4390
4391@item @code{hcidump} : could be used for low level debugging
4392@end itemize
4393
4394@c FIXME: A more unique name
4395@node How do I configure my peer2?
4396@subsection How do I configure my peer2?
4397
4398
4399On GNU/Linux, you just have to be sure that the interface name
4400corresponds to the one that you want to use.
4401Use the @code{hciconfig} tool to check that.
4402By default it is set to hci0 but you can change it.
4403
4404A basic configuration looks like this:
4405
4406@example
4407[transport-bluetooth]
4408# Name of the interface (typically hciX)
4409INTERFACE = hci0
4410# Real hardware, no testing
4411TESTMODE = 0 TESTING_IGNORE_KEYS = ACCEPT_FROM;
4412@end example
4413
4414In order to use the Bluetooth transport plugin when the transport service
4415is started, you must add the plugin name to the default transport service
4416plugins list. For example:
4417
4418@example
4419[transport] ... PLUGINS = dns bluetooth ...
4420@end example
4421
4422If you want to use only the Bluetooth plugin set
4423@emph{PLUGINS = bluetooth}
4424
4425On Windows, you cannot specify which device to use. The only thing that
4426you should do is to add @emph{bluetooth} on the plugins list of the
4427transport service.
4428
4429@node How can I test it?
4430@subsection How can I test it?
4431
4432
4433If you have two Bluetooth devices on the same machine and you are using
4434GNU/Linux you must:
4435
4436@itemize @bullet
4437
4438@item create two different file configuration (one which will use the
4439first interface (@emph{hci0}) and the other which will use the second
4440interface (@emph{hci1})). Let's name them @emph{peer1.conf} and
4441@emph{peer2.conf}.
4442
4443@item run @emph{gnunet-peerinfo -c peerX.conf -s} in order to generate the
4444peers private keys. The @strong{X} must be replace with 1 or 2.
4445
4446@item run @emph{gnunet-arm -c peerX.conf -s -i=transport} in order to
4447start the transport service. (Make sure that you have "bluetooth" on the
4448transport plugins list if the Bluetooth transport service doesn't start.)
4449
4450@item run @emph{gnunet-peerinfo -c peer1.conf -s} to get the first peer's
4451ID. If you already know your peer ID (you saved it from the first
4452command), this can be skipped.
4453
4454@item run @emph{gnunet-transport -c peer2.conf -p=PEER1_ID -s} to start
4455sending data for benchmarking to the other peer.
4456
4457@end itemize
4458
4459
4460This scenario will try to connect the second peer to the first one and
4461then start sending data for benchmarking.
4462
4463@c On Windows you cannot test the plugin functionality using two Bluetooth
4464@c devices from the same machine because after you install the drivers there
4465@c will occur some conflicts between the Bluetooth stacks. (At least that is
4466@c what happened on my machine : I wasn't able to use the Bluesoleil stack and
4467@c the WINDCOMM one in the same time).
4468
4469If you have two different machines and your configuration files are good
4470you can use the same scenario presented on the beginning of this section.
4471
4472Another way to test the plugin functionality is to create your own
4473application which will use the GNUnet framework with the Bluetooth
4474transport service.
4475
4476@node The implementation of the Bluetooth transport plugin
4477@subsection The implementation of the Bluetooth transport plugin
4478
4479
4480This page describes the implementation of the Bluetooth transport plugin.
4481
4482First I want to remind you that the Bluetooth transport plugin uses
4483virtually the same code as the WLAN plugin and only the helper binary is
4484different. Also the scope of the helper binary from the Bluetooth
4485transport plugin is the same as the one used for the WLAN transport
4486plugin: it accesses the interface and then it forwards traffic in both
4487directions between the Bluetooth interface and stdin/stdout of the
4488process involved.
4489
4490The Bluetooth plugin transport could be used both on GNU/Linux and Windows
4491platforms.
4492
4493@itemize @bullet
4494@item Linux functionality
4495@c @item Windows functionality
4496@item Pending Features
4497@end itemize
4498
4499
4500
4501@menu
4502* Linux functionality::
4503* THE INITIALIZATION::
4504* THE LOOP::
4505* Details about the broadcast implementation::
4506@c * Windows functionality::
4507* Pending features::
4508@end menu
4509
4510@node Linux functionality
4511@subsubsection Linux functionality
4512
4513
4514In order to implement the plugin functionality on GNU/Linux I
4515used the BlueZ stack.
4516For the communication with the other devices I used the RFCOMM
4517protocol. Also I used the HCI protocol to gain some control over the
4518device. The helper binary takes a single argument (the name of the
4519Bluetooth interface) and is separated in two stages:
4520
4521@c %** 'THE INITIALIZATION' should be in bigger letters or stand out, not
4522@c %** starting a new section?
4523@node THE INITIALIZATION
4524@subsubsection THE INITIALIZATION
4525
4526@itemize @bullet
4527@item first, it checks if we have root privileges
4528(@emph{Remember that we need to have root privileges in order to be able
4529to bring the interface up if it is down or to change its state.}).
4530
4531@item second, it verifies if the interface with the given name exists.
4532
4533@strong{If the interface with that name exists and it is a Bluetooth
4534interface:}
4535
4536@item it creates a RFCOMM socket which will be used for listening and call
4537the @emph{open_device} method
4538
4539On the @emph{open_device} method:
4540@itemize @bullet
4541@item creates a HCI socket used to send control events to the device
4542@item searches for the device ID using the interface name
4543@item saves the device MAC address
4544@item checks if the interface is down and tries to bring it UP
4545@item checks if the interface is in discoverable mode and tries to make it
4546discoverable
4547@item closes the HCI socket and binds the RFCOMM one
4548@item switches the RFCOMM socket in listening mode
4549@item registers the SDP service (the service will be used by the other
4550devices to get the port on which this device is listening on)
4551@end itemize
4552
4553@item drops the root privileges
4554
4555@strong{If the interface is not a Bluetooth interface the helper exits
4556with a suitable error}
4557@end itemize
4558
4559@c %** Same as for @node entry above
4560@node THE LOOP
4561@subsubsection THE LOOP
4562
4563The helper binary uses a list where it saves all the connected neighbour
4564devices (@emph{neighbours.devices}) and two buffers (@emph{write_pout} and
4565@emph{write_std}). The first message which is send is a control message
4566with the device's MAC address in order to announce the peer presence to
4567the neighbours. Here are a short description of what happens in the main
4568loop:
4569
4570@itemize @bullet
4571@item Every time when it receives something from the STDIN it processes
4572the data and saves the message in the first buffer (@emph{write_pout}).
4573When it has something in the buffer, it gets the destination address from
4574the buffer, searches the destination address in the list (if there is no
4575connection with that device, it creates a new one and saves it to the
4576list) and sends the message.
4577@item Every time when it receives something on the listening socket it
4578accepts the connection and saves the socket on a list with the reading
4579sockets. @item Every time when it receives something from a reading
4580socket it parses the message, verifies the CRC and saves it in the
4581@emph{write_std} buffer in order to be sent later to the STDOUT.
4582@end itemize
4583
4584So in the main loop we use the select function to wait until one of the
4585file descriptor saved in one of the two file descriptors sets used is
4586ready to use. The first set (@emph{rfds}) represents the reading set and
4587it could contain the list with the reading sockets, the STDIN file
4588descriptor or the listening socket. The second set (@emph{wfds}) is the
4589writing set and it could contain the sending socket or the STDOUT file
4590descriptor. After the select function returns, we check which file
4591descriptor is ready to use and we do what is supposed to do on that kind
4592of event. @emph{For example:} if it is the listening socket then we
4593accept a new connection and save the socket in the reading list; if it is
4594the STDOUT file descriptor, then we write to STDOUT the message from the
4595@emph{write_std} buffer.
4596
4597To find out on which port a device is listening on we connect to the local
4598SDP server and search the registered service for that device.
4599
4600@emph{You should be aware of the fact that if the device fails to connect
4601to another one when trying to send a message it will attempt one more
4602time. If it fails again, then it skips the message.}
4603@emph{Also you should know that the transport Bluetooth plugin has
4604support for @strong{broadcast messages}.}
4605
4606@node Details about the broadcast implementation
4607@subsubsection Details about the broadcast implementation
4608
4609
4610First I want to point out that the broadcast functionality for the CONTROL
4611messages is not implemented in a conventional way. Since the inquiry scan
4612time is too big and it will take some time to send a message to all the
4613discoverable devices I decided to tackle the problem in a different way.
4614Here is how I did it:
4615
4616@itemize @bullet
4617@item If it is the first time when I have to broadcast a message I make an
4618inquiry scan and save all the devices' addresses to a vector.
4619@item After the inquiry scan ends I take the first address from the list
4620and I try to connect to it. If it fails, I try to connect to the next one.
4621If it succeeds, I save the socket to a list and send the message to the
4622device.
4623@item When I have to broadcast another message, first I search on the list
4624for a new device which I'm not connected to. If there is no new device on
4625the list I go to the beginning of the list and send the message to the
4626old devices. After 5 cycles I make a new inquiry scan to check out if
4627there are new discoverable devices and save them to the list. If there
4628are no new discoverable devices I reset the cycling counter and go again
4629through the old list and send messages to the devices saved in it.
4630@end itemize
4631
4632@strong{Therefore}:
4633
4634@itemize @bullet
4635@item every time when I have a broadcast message I look up on the list
4636for a new device and send the message to it
4637@item if I reached the end of the list for 5 times and I'm connected to
4638all the devices from the list I make a new inquiry scan.
4639@emph{The number of the list's cycles after an inquiry scan could be
4640increased by redefining the MAX_LOOPS variable}
4641@item when there are no new devices I send messages to the old ones.
4642@end itemize
4643
4644Doing so, the broadcast control messages will reach the devices but with
4645delay.
4646
4647@emph{NOTICE:} When I have to send a message to a certain device first I
4648check on the broadcast list to see if we are connected to that device. If
4649not we try to connect to it and in case of success we save the address and
4650the socket on the list. If we are already connected to that device we
4651simply use the socket.
4652
4653@c @node Windows functionality
4654@c @subsubsection Windows functionality
4655
4656
4657@c For Windows I decided to use the Microsoft Bluetooth stack which has the
4658@c advantage of coming standard from Windows XP SP2. The main disadvantage is
4659@c that it only supports the RFCOMM protocol so we will not be able to have
4660@c a low level control over the Bluetooth device. Therefore it is the user
4661@c responsibility to check if the device is up and in the discoverable mode.
4662@c Also there are no tools which could be used for debugging in order to read
4663@c the data coming from and going to a Bluetooth device, which obviously
4664@c hindered my work. Another thing that slowed down the implementation of the
4665@c plugin (besides that I wasn't too accommodated with the win32 API) was that
4666@c there were some bugs on MinGW regarding the Bluetooth. Now they are solved
4667@c but you should keep in mind that you should have the latest updates
4668@c (especially the @emph{ws2bth} header).
4669
4670@c Besides the fact that it uses the Windows Sockets, the Windows
4671@c implementation follows the same principles as the GNU/Linux one:
4672
4673@c @itemize @bullet
4674@c @item It has a initialization part where it initializes the
4675@c Windows Sockets, creates a RFCOMM socket which will be binded and switched
4676@c to the listening mode and registers a SDP service. In the Microsoft
4677@c Bluetooth API there are two ways to work with the SDP:
4678@c @itemize @bullet
4679@c @item an easy way which works with very simple service records
4680@c @item a hard way which is useful when you need to update or to delete the
4681@c record
4682@c @end itemize
4683@c @end itemize
4684
4685@c Since I only needed the SDP service to find out on which port the device
4686@c is listening on and that did not change, I decided to use the easy way.
4687@c In order to register the service I used the @emph{WSASetService} function
4688@c and I generated the @emph{Universally Unique Identifier} with the
4689@c @emph{guidgen.exe} Windows's tool.
4690
4691@c In the loop section the only difference from the GNU/Linux implementation
4692@c is that I used the @code{GNUNET_NETWORK} library for
4693@c functions like @emph{accept}, @emph{bind}, @emph{connect} or
4694@c @emph{select}. I decided to use the
4695@c @code{GNUNET_NETWORK} library because I also needed to interact
4696@c with the STDIN and STDOUT handles and on Windows
4697@c the select function is only defined for sockets,
4698@c and it will not work for arbitrary file handles.
4699
4700@c Another difference between GNU/Linux and Windows implementation is that in
4701@c GNU/Linux, the Bluetooth address is represented in 48 bits
4702@c while in Windows is represented in 64 bits.
4703@c Therefore I had to do some changes on @emph{plugin_transport_wlan} header.
4704
4705@c Also, currently on Windows the Bluetooth plugin doesn't have support for
4706@c broadcast messages. When it receives a broadcast message it will skip it.
4707
4708@node Pending features
4709@subsubsection Pending features
4710
4711
4712@itemize @bullet
4713@c @item Implement the broadcast functionality on Windows @emph{(currently
4714@c working on)}
4715@item Implement a testcase for the helper :@ @emph{The testcase
4716consists of a program which emulates the plugin and uses the helper. It
4717will simulate connections, disconnections and data transfers.}
4718@end itemize
4719
4720If you have a new idea about a feature of the plugin or suggestions about
4721how I could improve the implementation you are welcome to comment or to
4722contact me.
4723
4724@node WLAN plugin
4725@section WLAN plugin
4726
4727
4728This section documents how the wlan transport plugin works. Parts which
4729are not implemented yet or could be better implemented are described at
4730the end.
4731
4732@cindex ATS Subsystem
4733@node ATS Subsystem
4734@section ATS Subsystem
4735
4736
4737ATS stands for "automatic transport selection", and the function of ATS in
4738GNUnet is to decide on which address (and thus transport plugin) should
4739be used for two peers to communicate, and what bandwidth limits should be
4740imposed on such an individual connection. To help ATS make an informed
4741decision, higher-level services inform the ATS service about their
4742requirements and the quality of the service rendered. The ATS service
4743also interacts with the transport service to be appraised of working
4744addresses and to communicate its resource allocation decisions. Finally,
4745the ATS service's operation can be observed using a monitoring API.
4746
4747The main logic of the ATS service only collects the available addresses,
4748their performance characteristics and the applications requirements, but
4749does not make the actual allocation decision. This last critical step is
4750left to an ATS plugin, as we have implemented (currently three) different
4751allocation strategies which differ significantly in their performance and
4752maturity, and it is still unclear if any particular plugin is generally
4753superior.
4754
4755@cindex CORE Subsystem
4756@node CORE Subsystem
4757@section CORE Subsystem
4758
4759
4760The CORE subsystem in GNUnet is responsible for securing link-layer
4761communications between nodes in the GNUnet overlay network. CORE builds
4762on the TRANSPORT subsystem which provides for the actual, insecure,
4763unreliable link-layer communication (for example, via UDP or WLAN), and
4764then adds fundamental security to the connections:
4765
4766@itemize @bullet
4767@item confidentiality with so-called perfect forward secrecy; we use
4768ECDHE
4769(@uref{http://en.wikipedia.org/wiki/Elliptic_curve_Diffie%E2%80%93Hellman, Elliptic-curve Diffie---Hellman})
4770powered by Curve25519
4771(@uref{http://cr.yp.to/ecdh.html, Curve25519}) for the key
4772exchange and then use symmetric encryption, encrypting with both AES-256
4773(@uref{http://en.wikipedia.org/wiki/Rijndael, AES-256}) and
4774Twofish (@uref{http://en.wikipedia.org/wiki/Twofish, Twofish})
4775@item @uref{http://en.wikipedia.org/wiki/Authentication, authentication}
4776is achieved by signing the ephemeral keys using Ed25519
4777(@uref{http://ed25519.cr.yp.to/, Ed25519}), a deterministic
4778variant of ECDSA
4779(@uref{http://en.wikipedia.org/wiki/ECDSA, ECDSA})
4780@item integrity protection (using SHA-512
4781(@uref{http://en.wikipedia.org/wiki/SHA-2, SHA-512}) to do
4782encrypt-then-MAC
4783(@uref{http://en.wikipedia.org/wiki/Authenticated_encryption, encrypt-then-MAC}))
4784@item Replay
4785(@uref{http://en.wikipedia.org/wiki/Replay_attack, replay})
4786protection (using nonces, timestamps, challenge-response,
4787message counters and ephemeral keys)
4788@item liveness (keep-alive messages, timeout)
4789@end itemize
4790
4791@menu
4792* Limitations::
4793* When is a peer "connected"?::
4794* libgnunetcore::
4795* The CORE Client-Service Protocol::
4796* The CORE Peer-to-Peer Protocol::
4797@end menu
4798
4799@cindex core subsystem limitations
4800@node Limitations
4801@subsection Limitations
4802
4803
4804CORE does not perform
4805@uref{http://en.wikipedia.org/wiki/Routing, routing}; using CORE it is
4806only possible to communicate with peers that happen to already be
4807"directly" connected with each other. CORE also does not have an
4808API to allow applications to establish such "direct" connections --- for
4809this, applications can ask TRANSPORT, but TRANSPORT might not be able to
4810establish a "direct" connection. The TOPOLOGY subsystem is responsible for
4811trying to keep a few "direct" connections open at all times. Applications
4812that need to talk to particular peers should use the CADET subsystem, as
4813it can establish arbitrary "indirect" connections.
4814
4815Because CORE does not perform routing, CORE must only be used directly by
4816applications that either perform their own routing logic (such as
4817anonymous file-sharing) or that do not require routing, for example
4818because they are based on flooding the network. CORE communication is
4819unreliable and delivery is possibly out-of-order. Applications that
4820require reliable communication should use the CADET service. Each
4821application can only queue one message per target peer with the CORE
4822service at any time; messages cannot be larger than approximately
482363 kilobytes. If messages are small, CORE may group multiple messages
4824(possibly from different applications) prior to encryption. If permitted
4825by the application (using the @uref{http://baus.net/on-tcp_cork/, cork}
4826option), CORE may delay transmissions to facilitate grouping of multiple
4827small messages. If cork is not enabled, CORE will transmit the message as
4828soon as TRANSPORT allows it (TRANSPORT is responsible for limiting
4829bandwidth and congestion control). CORE does not allow flow control;
4830applications are expected to process messages at line-speed. If flow
4831control is needed, applications should use the CADET service.
4832
4833@cindex when is a peer connected
4834@node When is a peer "connected"?
4835@subsection When is a peer "connected"?
4836
4837
4838In addition to the security features mentioned above, CORE also provides
4839one additional key feature to applications using it, and that is a
4840limited form of protocol-compatibility checking. CORE distinguishes
4841between TRANSPORT-level connections (which enable communication with other
4842peers) and application-level connections. Applications using the CORE API
4843will (typically) learn about application-level connections from CORE, and
4844not about TRANSPORT-level connections. When a typical application uses
4845CORE, it will specify a set of message types
4846(from @code{gnunet_protocols.h}) that it understands. CORE will then
4847notify the application about connections it has with other peers if and
4848only if those applications registered an intersecting set of message
4849types with their CORE service. Thus, it is quite possible that CORE only
4850exposes a subset of the established direct connections to a particular
4851application --- and different applications running above CORE might see
4852different sets of connections at the same time.
4853
4854A special case are applications that do not register a handler for any
4855message type.
4856CORE assumes that these applications merely want to monitor connections
4857(or "all" messages via other callbacks) and will notify those applications
4858about all connections. This is used, for example, by the
4859@code{gnunet-core} command-line tool to display the active connections.
4860Note that it is also possible that the TRANSPORT service has more active
4861connections than the CORE service, as the CORE service first has to
4862perform a key exchange with connecting peers before exchanging information
4863about supported message types and notifying applications about the new
4864connection.
4865
4866@cindex libgnunetcore
4867@node libgnunetcore
4868@subsection libgnunetcore
4869
4870
4871The CORE API (defined in @file{gnunet_core_service.h}) is the basic
4872messaging API used by P2P applications built using GNUnet. It provides
4873applications the ability to send and receive encrypted messages to the
4874peer's "directly" connected neighbours.
4875
4876As CORE connections are generally "direct" connections,@ applications must
4877not assume that they can connect to arbitrary peers this way, as "direct"
4878connections may not always be possible. Applications using CORE are
4879notified about which peers are connected. Creating new "direct"
4880connections must be done using the TRANSPORT API.
4881
4882The CORE API provides unreliable, out-of-order delivery. While the
4883implementation tries to ensure timely, in-order delivery, both message
4884losses and reordering are not detected and must be tolerated by the
4885application. Most important, the core will NOT perform retransmission if
4886messages could not be delivered.
4887
4888Note that CORE allows applications to queue one message per connected
4889peer. The rate at which each connection operates is influenced by the
4890preferences expressed by local application as well as restrictions
4891imposed by the other peer. Local applications can express their
4892preferences for particular connections using the "performance" API of the
4893ATS service.
4894
4895Applications that require more sophisticated transmission capabilities
4896such as TCP-like behavior, or if you intend to send messages to arbitrary
4897remote peers, should use the CADET API.
4898
4899The typical use of the CORE API is to connect to the CORE service using
4900@code{GNUNET_CORE_connect}, process events from the CORE service (such as
4901peers connecting, peers disconnecting and incoming messages) and send
4902messages to connected peers using
4903@code{GNUNET_CORE_notify_transmit_ready}. Note that applications must
4904cancel pending transmission requests if they receive a disconnect event
4905for a peer that had a transmission pending; furthermore, queuing more
4906than one transmission request per peer per application using the
4907service is not permitted.
4908
4909The CORE API also allows applications to monitor all communications of the
4910peer prior to encryption (for outgoing messages) or after decryption (for
4911incoming messages). This can be useful for debugging, diagnostics or to
4912establish the presence of cover traffic (for anonymity). As monitoring
4913applications are often not interested in the payload, the monitoring
4914callbacks can be configured to only provide the message headers (including
4915the message type and size) instead of copying the full data stream to the
4916monitoring client.
4917
4918The init callback of the @code{GNUNET_CORE_connect} function is called
4919with the hash of the public key of the peer. This public key is used to
4920identify the peer globally in the GNUnet network. Applications are
4921encouraged to check that the provided hash matches the hash that they are
4922using (as theoretically the application may be using a different
4923configuration file with a different private key, which would result in
4924hard to find bugs).
4925
4926As with most service APIs, the CORE API isolates applications from crashes
4927of the CORE service. If the CORE service crashes, the application will see
4928disconnect events for all existing connections. Once the connections are
4929re-established, the applications will be receive matching connect events.
4930
4931@cindex core clinet-service protocol
4932@node The CORE Client-Service Protocol
4933@subsection The CORE Client-Service Protocol
4934
4935
4936This section describes the protocol between an application using the CORE
4937service (the client) and the CORE service process itself.
4938
4939
4940@menu
4941* Setup2::
4942* Notifications::
4943* Sending::
4944@end menu
4945
4946@node Setup2
4947@subsubsection Setup2
4948
4949
4950When a client connects to the CORE service, it first sends a
4951@code{InitMessage} which specifies options for the connection and a set of
4952message type values which are supported by the application. The options
4953bitmask specifies which events the client would like to be notified about.
4954The options include:
4955
4956@table @asis
4957@item GNUNET_CORE_OPTION_NOTHING No notifications
4958@item GNUNET_CORE_OPTION_STATUS_CHANGE Peers connecting and disconnecting
4959@item GNUNET_CORE_OPTION_FULL_INBOUND All inbound messages (after
4960decryption) with full payload
4961@item GNUNET_CORE_OPTION_HDR_INBOUND Just the @code{MessageHeader}
4962of all inbound messages
4963@item GNUNET_CORE_OPTION_FULL_OUTBOUND All outbound
4964messages (prior to encryption) with full payload
4965@item GNUNET_CORE_OPTION_HDR_OUTBOUND Just the @code{MessageHeader} of all
4966outbound messages
4967@end table
4968
4969Typical applications will only monitor for connection status changes.
4970
4971The CORE service responds to the @code{InitMessage} with an
4972@code{InitReplyMessage} which contains the peer's identity. Afterwards,
4973both CORE and the client can send messages.
4974
4975@node Notifications
4976@subsubsection Notifications
4977
4978
4979The CORE will send @code{ConnectNotifyMessage}s and
4980@code{DisconnectNotifyMessage}s whenever peers connect or disconnect from
4981the CORE (assuming their type maps overlap with the message types
4982registered by the client). When the CORE receives a message that matches
4983the set of message types specified during the @code{InitMessage} (or if
4984monitoring is enabled in for inbound messages in the options), it sends a
4985@code{NotifyTrafficMessage} with the peer identity of the sender and the
4986decrypted payload. The same message format (except with
4987@code{GNUNET_MESSAGE_TYPE_CORE_NOTIFY_OUTBOUND} for the message type) is
4988used to notify clients monitoring outbound messages; here, the peer
4989identity given is that of the receiver.
4990
4991@node Sending
4992@subsubsection Sending
4993
4994
4995When a client wants to transmit a message, it first requests a
4996transmission slot by sending a @code{SendMessageRequest} which specifies
4997the priority, deadline and size of the message. Note that these values
4998may be ignored by CORE. When CORE is ready for the message, it answers
4999with a @code{SendMessageReady} response. The client can then transmit the
5000payload with a @code{SendMessage} message. Note that the actual message
5001size in the @code{SendMessage} is allowed to be smaller than the size in
5002the original request. A client may at any time send a fresh
5003@code{SendMessageRequest}, which then superceeds the previous
5004@code{SendMessageRequest}, which is then no longer valid. The client can
5005tell which @code{SendMessageRequest} the CORE service's
5006@code{SendMessageReady} message is for as all of these messages contain a
5007"unique" request ID (based on a counter incremented by the client
5008for each request).
5009
5010@cindex CORE Peer-to-Peer Protocol
5011@node The CORE Peer-to-Peer Protocol
5012@subsection The CORE Peer-to-Peer Protocol
5013
5014
5015
5016@menu
5017* Creating the EphemeralKeyMessage::
5018* Establishing a connection::
5019* Encryption and Decryption::
5020* Type maps::
5021@end menu
5022
5023@cindex EphemeralKeyMessage creation
5024@node Creating the EphemeralKeyMessage
5025@subsubsection Creating the EphemeralKeyMessage
5026
5027
5028When the CORE service starts, each peer creates a fresh ephemeral (ECC)
5029public-private key pair and signs the corresponding
5030@code{EphemeralKeyMessage} with its long-term key (which we usually call
5031the peer's identity; the hash of the public long term key is what results
5032in a @code{struct GNUNET_PeerIdentity} in all GNUnet APIs. The ephemeral
5033key is ONLY used for an ECDHE
5034(@uref{http://en.wikipedia.org/wiki/Elliptic_curve_Diffie%E2%80%93Hellman, Elliptic-curve Diffie---Hellman})
5035exchange by the CORE service to establish symmetric session keys. A peer
5036will use the same @code{EphemeralKeyMessage} for all peers for
5037@code{REKEY_FREQUENCY}, which is usually 12 hours. After that time, it
5038will create a fresh ephemeral key (forgetting the old one) and broadcast
5039the new @code{EphemeralKeyMessage} to all connected peers, resulting in
5040fresh symmetric session keys. Note that peers independently decide on
5041when to discard ephemeral keys; it is not a protocol violation to discard
5042keys more often. Ephemeral keys are also never stored to disk; restarting
5043a peer will thus always create a fresh ephemeral key. The use of ephemeral
5044keys is what provides @uref{http://en.wikipedia.org/wiki/Forward_secrecy, forward secrecy}.
5045
5046Just before transmission, the @code{EphemeralKeyMessage} is patched to
5047reflect the current sender_status, which specifies the current state of
5048the connection from the point of view of the sender. The possible values
5049are:
5050
5051@itemize @bullet
5052@item @code{KX_STATE_DOWN} Initial value, never used on the network
5053@item @code{KX_STATE_KEY_SENT} We sent our ephemeral key, do not know the
5054key of the other peer
5055@item @code{KX_STATE_KEY_RECEIVED} This peer has received a valid
5056ephemeral key of the other peer, but we are waiting for the other peer to
5057confirm it's authenticity (ability to decode) via challenge-response.
5058@item @code{KX_STATE_UP} The connection is fully up from the point of
5059view of the sender (now performing keep-alive)
5060@item @code{KX_STATE_REKEY_SENT} The sender has initiated a rekeying
5061operation; the other peer has so far failed to confirm a working
5062connection using the new ephemeral key
5063@end itemize
5064
5065@node Establishing a connection
5066@subsubsection Establishing a connection
5067
5068
5069Peers begin their interaction by sending a @code{EphemeralKeyMessage} to
5070the other peer once the TRANSPORT service notifies the CORE service about
5071the connection.
5072A peer receiving an @code{EphemeralKeyMessage} with a status
5073indicating that the sender does not have the receiver's ephemeral key, the
5074receiver's @code{EphemeralKeyMessage} is sent in response.
5075Additionally, if the receiver has not yet confirmed the authenticity of
5076the sender, it also sends an (encrypted)@code{PingMessage} with a
5077challenge (and the identity of the target) to the other peer. Peers
5078receiving a @code{PingMessage} respond with an (encrypted)
5079@code{PongMessage} which includes the challenge. Peers receiving a
5080@code{PongMessage} check the challenge, and if it matches set the
5081connection to @code{KX_STATE_UP}.
5082
5083@node Encryption and Decryption
5084@subsubsection Encryption and Decryption
5085
5086
5087All functions related to the key exchange and encryption/decryption of
5088messages can be found in @file{gnunet-service-core_kx.c} (except for the
5089cryptographic primitives, which are in @file{util/crypto*.c}).
5090Given the key material from ECDHE, a Key derivation function
5091(@uref{https://en.wikipedia.org/wiki/Key_derivation_function, Key derivation function})
5092is used to derive two pairs of encryption and decryption keys for AES-256
5093and TwoFish, as well as initialization vectors and authentication keys
5094(for HMAC
5095(@uref{https://en.wikipedia.org/wiki/HMAC, HMAC})).
5096The HMAC is computed over the encrypted payload.
5097Encrypted messages include an iv_seed and the HMAC in the header.
5098
5099Each encrypted message in the CORE service includes a sequence number and
5100a timestamp in the encrypted payload. The CORE service remembers the
5101largest observed sequence number and a bit-mask which represents which of
5102the previous 32 sequence numbers were already used.
5103Messages with sequence numbers lower than the largest observed sequence
5104number minus 32 are discarded. Messages with a timestamp that is less
5105than @code{REKEY_TOLERANCE} off (5 minutes) are also discarded. This of
5106course means that system clocks need to be reasonably synchronized for
5107peers to be able to communicate. Additionally, as the ephemeral key
5108changes every 12 hours, a peer would not even be able to decrypt messages
5109older than 12 hours.
5110
5111@node Type maps
5112@subsubsection Type maps
5113
5114
5115Once an encrypted connection has been established, peers begin to exchange
5116type maps. Type maps are used to allow the CORE service to determine which
5117(encrypted) connections should be shown to which applications. A type map
5118is an array of 65536 bits representing the different types of messages
5119understood by applications using the CORE service. Each CORE service
5120maintains this map, simply by setting the respective bit for each message
5121type supported by any of the applications using the CORE service. Note
5122that bits for message types embedded in higher-level protocols (such as
5123MESH) will not be included in these type maps.
5124
5125Typically, the type map of a peer will be sparse. Thus, the CORE service
5126attempts to compress its type map using @code{gzip}-style compression
5127("deflate") prior to transmission. However, if the compression fails to
5128compact the map, the map may also be transmitted without compression
5129(resulting in @code{GNUNET_MESSAGE_TYPE_CORE_COMPRESSED_TYPE_MAP} or
5130@code{GNUNET_MESSAGE_TYPE_CORE_BINARY_TYPE_MAP} messages respectively).
5131Upon receiving a type map, the respective CORE service notifies
5132applications about the connection to the other peer if they support any
5133message type indicated in the type map (or no message type at all).
5134If the CORE service experience a connect or disconnect event from an
5135application, it updates its type map (setting or unsetting the respective
5136bits) and notifies its neighbours about the change.
5137The CORE services of the neighbours then in turn generate connect and
5138disconnect events for the peer that sent the type map for their respective
5139applications. As CORE messages may be lost, the CORE service confirms
5140receiving a type map by sending back a
5141@code{GNUNET_MESSAGE_TYPE_CORE_CONFIRM_TYPE_MAP}. If such a confirmation
5142(with the correct hash of the type map) is not received, the sender will
5143retransmit the type map (with exponential back-off).
5144
5145@cindex CADET Subsystem
5146@cindex CADET
5147@cindex cadet
5148@node CADET Subsystem
5149@section CADET Subsystem
5150
5151The CADET subsystem in GNUnet is responsible for secure end-to-end
5152communications between nodes in the GNUnet overlay network. CADET builds
5153on the CORE subsystem which provides for the link-layer communication and
5154then adds routing, forwarding and additional security to the connections.
5155CADET offers the same cryptographic services as CORE, but on an
5156end-to-end level. This is done so peers retransmitting traffic on behalf
5157of other peers cannot access the payload data.
5158
5159@itemize @bullet
5160@item CADET provides confidentiality with so-called perfect forward
5161secrecy; we use ECDHE powered by Curve25519 for the key exchange and then
5162use symmetric encryption, encrypting with both AES-256 and Twofish
5163@item authentication is achieved by signing the ephemeral keys using
5164Ed25519, a deterministic variant of ECDSA
5165@item integrity protection (using SHA-512 to do encrypt-then-MAC, although
5166only 256 bits are sent to reduce overhead)
5167@item replay protection (using nonces, timestamps, challenge-response,
5168message counters and ephemeral keys)
5169@item liveness (keep-alive messages, timeout)
5170@end itemize
5171
5172Additional to the CORE-like security benefits, CADET offers other
5173properties that make it a more universal service than CORE.
5174
5175@itemize @bullet
5176@item CADET can establish channels to arbitrary peers in GNUnet. If a
5177peer is not immediately reachable, CADET will find a path through the
5178network and ask other peers to retransmit the traffic on its behalf.
5179@item CADET offers (optional) reliability mechanisms. In a reliable
5180channel traffic is guaranteed to arrive complete, unchanged and in-order.
5181@item CADET takes care of flow and congestion control mechanisms, not
5182allowing the sender to send more traffic than the receiver or the network
5183are able to process.
5184@end itemize
5185
5186@menu
5187* libgnunetcadet::
5188@end menu
5189
5190@cindex libgnunetcadet
5191@node libgnunetcadet
5192@subsection libgnunetcadet
5193
5194
5195The CADET API (defined in @file{gnunet_cadet_service.h}) is the
5196messaging API used by P2P applications built using GNUnet.
5197It provides applications the ability to send and receive encrypted
5198messages to any peer participating in GNUnet.
5199The API is heavily base on the CORE API.
5200
5201CADET delivers messages to other peers in "channels".
5202A channel is a permanent connection defined by a destination peer
5203(identified by its public key) and a port number.
5204Internally, CADET tunnels all channels towards a destination peer
5205using one session key and relays the data on multiple "connections",
5206independent from the channels.
5207
5208Each channel has optional parameters, the most important being the
5209reliability flag.
5210Should a message get lost on TRANSPORT/CORE level, if a channel is
5211created with as reliable, CADET will retransmit the lost message and
5212deliver it in order to the destination application.
5213
5214@pindex GNUNET_CADET_connect
5215To communicate with other peers using CADET, it is necessary to first
5216connect to the service using @code{GNUNET_CADET_connect}.
5217This function takes several parameters in form of callbacks, to allow the
5218client to react to various events, like incoming channels or channels that
5219terminate, as well as specify a list of ports the client wishes to listen
5220to (at the moment it is not possible to start listening on further ports
5221once connected, but nothing prevents a client to connect several times to
5222CADET, even do one connection per listening port).
5223The function returns a handle which has to be used for any further
5224interaction with the service.
5225
5226@pindex GNUNET_CADET_channel_create
5227To connect to a remote peer, a client has to call the
5228@code{GNUNET_CADET_channel_create} function. The most important parameters
5229given are the remote peer's identity (it public key) and a port, which
5230specifies which application on the remote peer to connect to, similar to
5231TCP/UDP ports. CADET will then find the peer in the GNUnet network and
5232establish the proper low-level connections and do the necessary key
5233exchanges to assure and authenticated, secure and verified communication.
5234Similar to @code{GNUNET_CADET_connect},@code{GNUNET_CADET_create_channel}
5235returns a handle to interact with the created channel.
5236
5237@pindex GNUNET_CADET_notify_transmit_ready
5238For every message the client wants to send to the remote application,
5239@code{GNUNET_CADET_notify_transmit_ready} must be called, indicating the
5240channel on which the message should be sent and the size of the message
5241(but not the message itself!). Once CADET is ready to send the message,
5242the provided callback will fire, and the message contents are provided to
5243this callback.
5244
5245Please note the CADET does not provide an explicit notification of when a
5246channel is connected. In loosely connected networks, like big wireless
5247mesh networks, this can take several seconds, even minutes in the worst
5248case. To be alerted when a channel is online, a client can call
5249@code{GNUNET_CADET_notify_transmit_ready} immediately after
5250@code{GNUNET_CADET_create_channel}. When the callback is activated, it
5251means that the channel is online. The callback can give 0 bytes to CADET
5252if no message is to be sent, this is OK.
5253
5254@pindex GNUNET_CADET_notify_transmit_cancel
5255If a transmission was requested but before the callback fires it is no
5256longer needed, it can be canceled with
5257@code{GNUNET_CADET_notify_transmit_ready_cancel}, which uses the handle
5258given back by @code{GNUNET_CADET_notify_transmit_ready}.
5259As in the case of CORE, only one message can be requested at a time: a
5260client must not call @code{GNUNET_CADET_notify_transmit_ready} again until
5261the callback is called or the request is canceled.
5262
5263@pindex GNUNET_CADET_channel_destroy
5264When a channel is no longer needed, a client can call
5265@code{GNUNET_CADET_channel_destroy} to get rid of it.
5266Note that CADET will try to transmit all pending traffic before notifying
5267the remote peer of the destruction of the channel, including
5268retransmitting lost messages if the channel was reliable.
5269
5270Incoming channels, channels being closed by the remote peer, and traffic
5271on any incoming or outgoing channels are given to the client when CADET
5272executes the callbacks given to it at the time of
5273@code{GNUNET_CADET_connect}.
5274
5275@pindex GNUNET_CADET_disconnect
5276Finally, when an application no longer wants to use CADET, it should call
5277@code{GNUNET_CADET_disconnect}, but first all channels and pending
5278transmissions must be closed (otherwise CADET will complain).
5279
5280@cindex NSE Subsystem
5281@node NSE Subsystem
5282@section NSE Subsystem
5283
5284
5285NSE stands for @dfn{Network Size Estimation}. The NSE subsystem provides
5286other subsystems and users with a rough estimate of the number of peers
5287currently participating in the GNUnet overlay.
5288The computed value is not a precise number as producing a precise number
5289in a decentralized, efficient and secure way is impossible.
5290While NSE's estimate is inherently imprecise, NSE also gives the expected
5291range. For a peer that has been running in a stable network for a
5292while, the real network size will typically (99.7% of the time) be in the
5293range of [2/3 estimate, 3/2 estimate]. We will now give an overview of the
5294algorithm used to calculate the estimate;
5295all of the details can be found in this technical report.
5296
5297@c FIXME: link to the report.
5298
5299@menu
5300* Motivation::
5301* Principle::
5302* libgnunetnse::
5303* The NSE Client-Service Protocol::
5304* The NSE Peer-to-Peer Protocol::
5305@end menu
5306
5307@node Motivation
5308@subsection Motivation
5309
5310
5311Some subsystems, like DHT, need to know the size of the GNUnet network to
5312optimize some parameters of their own protocol. The decentralized nature
5313of GNUnet makes efficient and securely counting the exact number of peers
5314infeasible. Although there are several decentralized algorithms to count
5315the number of peers in a system, so far there is none to do so securely.
5316Other protocols may allow any malicious peer to manipulate the final
5317result or to take advantage of the system to perform
5318@dfn{Denial of Service} (DoS) attacks against the network.
5319GNUnet's NSE protocol avoids these drawbacks.
5320
5321
5322
5323@menu
5324* Security::
5325@end menu
5326
5327@cindex NSE security
5328@cindex nse security
5329@node Security
5330@subsubsection Security
5331
5332
5333The NSE subsystem is designed to be resilient against these attacks.
5334It uses @uref{http://en.wikipedia.org/wiki/Proof-of-work_system, proofs of work}
5335to prevent one peer from impersonating a large number of participants,
5336which would otherwise allow an adversary to artificially inflate the
5337estimate.
5338The DoS protection comes from the time-based nature of the protocol:
5339the estimates are calculated periodically and out-of-time traffic is
5340either ignored or stored for later retransmission by benign peers.
5341In particular, peers cannot trigger global network communication at will.
5342
5343@cindex NSE principle
5344@cindex nse principle
5345@node Principle
5346@subsection Principle
5347
5348
5349The algorithm calculates the estimate by finding the globally closest
5350peer ID to a random, time-based value.
5351
5352The idea is that the closer the ID is to the random value, the more
5353"densely packed" the ID space is, and therefore, more peers are in the
5354network.
5355
5356
5357
5358@menu
5359* Example::
5360* Algorithm::
5361* Target value::
5362* Timing::
5363* Controlled Flooding::
5364* Calculating the estimate::
5365@end menu
5366
5367@node Example
5368@subsubsection Example
5369
5370
5371Suppose all peers have IDs between 0 and 100 (our ID space), and the
5372random value is 42.
5373If the closest peer has the ID 70 we can imagine that the average
5374"distance" between peers is around 30 and therefore the are around 3
5375peers in the whole ID space. On the other hand, if the closest peer has
5376the ID 44, we can imagine that the space is rather packed with peers,
5377maybe as much as 50 of them.
5378Naturally, we could have been rather unlucky, and there is only one peer
5379and happens to have the ID 44. Thus, the current estimate is calculated
5380as the average over multiple rounds, and not just a single sample.
5381
5382@node Algorithm
5383@subsubsection Algorithm
5384
5385
5386Given that example, one can imagine that the job of the subsystem is to
5387efficiently communicate the ID of the closest peer to the target value
5388to all the other peers, who will calculate the estimate from it.
5389
5390@node Target value
5391@subsubsection Target value
5392
5393
5394
5395The target value itself is generated by hashing the current time, rounded
5396down to an agreed value. If the rounding amount is 1h (default) and the
5397time is 12:34:56, the time to hash would be 12:00:00. The process is
5398repeated each rounding amount (in this example would be every hour).
5399Every repetition is called a round.
5400
5401@node Timing
5402@subsubsection Timing
5403
5404
5405The NSE subsystem has some timing control to avoid everybody broadcasting
5406its ID all at one. Once each peer has the target random value, it
5407compares its own ID to the target and calculates the hypothetical size of
5408the network if that peer were to be the closest.
5409Then it compares the hypothetical size with the estimate from the previous
5410rounds. For each value there is an associated point in the period,
5411let's call it "broadcast time". If its own hypothetical estimate
5412is the same as the previous global estimate, its "broadcast time" will be
5413in the middle of the round. If its bigger it will be earlier and if its
5414smaller (the most likely case) it will be later. This ensures that the
5415peers closest to the target value start broadcasting their ID the first.
5416
5417@node Controlled Flooding
5418@subsubsection Controlled Flooding
5419
5420
5421
5422When a peer receives a value, first it verifies that it is closer than the
5423closest value it had so far, otherwise it answers the incoming message
5424with a message containing the better value. Then it checks a proof of
5425work that must be included in the incoming message, to ensure that the
5426other peer's ID is not made up (otherwise a malicious peer could claim to
5427have an ID of exactly the target value every round). Once validated, it
5428compares the broadcast time of the received value with the current time
5429and if it's not too early, sends the received value to its neighbors.
5430Otherwise it stores the value until the correct broadcast time comes.
5431This prevents unnecessary traffic of sub-optimal values, since a better
5432value can come before the broadcast time, rendering the previous one
5433obsolete and saving the traffic that would have been used to broadcast it
5434to the neighbors.
5435
5436@node Calculating the estimate
5437@subsubsection Calculating the estimate
5438
5439
5440
5441Once the closest ID has been spread across the network each peer gets the
5442exact distance between this ID and the target value of the round and
5443calculates the estimate with a mathematical formula described in the tech
5444report. The estimate generated with this method for a single round is not
5445very precise. Remember the case of the example, where the only peer is the
5446ID 44 and we happen to generate the target value 42, thinking there are
544750 peers in the network. Therefore, the NSE subsystem remembers the last
544864 estimates and calculates an average over them, giving a result of which
5449usually has one bit of uncertainty (the real size could be half of the
5450estimate or twice as much). Note that the actual network size is
5451calculated in powers of two of the raw input, thus one bit of uncertainty
5452means a factor of two in the size estimate.
5453
5454@cindex libgnunetnse
5455@node libgnunetnse
5456@subsection libgnunetnse
5457
5458
5459
5460The NSE subsystem has the simplest API of all services, with only two
5461calls: @code{GNUNET_NSE_connect} and @code{GNUNET_NSE_disconnect}.
5462
5463The connect call gets a callback function as a parameter and this function
5464is called each time the network agrees on an estimate. This usually is
5465once per round, with some exceptions: if the closest peer has a late
5466local clock and starts spreading its ID after everyone else agreed on a
5467value, the callback might be activated twice in a round, the second value
5468being always bigger than the first. The default round time is set to
54691 hour.
5470
5471The disconnect call disconnects from the NSE subsystem and the callback
5472is no longer called with new estimates.
5473
5474
5475
5476@menu
5477* Results::
5478* libgnunetnse - Examples::
5479@end menu
5480
5481@node Results
5482@subsubsection Results
5483
5484
5485
5486The callback provides two values: the average and the
5487@uref{http://en.wikipedia.org/wiki/Standard_deviation, standard deviation}
5488of the last 64 rounds. The values provided by the callback function are
5489logarithmic, this means that the real estimate numbers can be obtained by
5490calculating 2 to the power of the given value (2average). From a
5491statistics point of view this means that:
5492
5493@itemize @bullet
5494@item 68% of the time the real size is included in the interval
5495[(2average-stddev), 2]
5496@item 95% of the time the real size is included in the interval
5497[(2average-2*stddev, 2^average+2*stddev]
5498@item 99.7% of the time the real size is included in the interval
5499[(2average-3*stddev, 2average+3*stddev]
5500@end itemize
5501
5502The expected standard variation for 64 rounds in a network of stable size
5503is 0.2. Thus, we can say that normally:
5504
5505@itemize @bullet
5506@item 68% of the time the real size is in the range [-13%, +15%]
5507@item 95% of the time the real size is in the range [-24%, +32%]
5508@item 99.7% of the time the real size is in the range [-34%, +52%]
5509@end itemize
5510
5511As said in the introduction, we can be quite sure that usually the real
5512size is between one third and three times the estimate. This can of
5513course vary with network conditions.
5514Thus, applications may want to also consider the provided standard
5515deviation value, not only the average (in particular, if the standard
5516variation is very high, the average maybe meaningless: the network size is
5517changing rapidly).
5518
5519@node libgnunetnse - Examples
5520@subsubsection libgnunetnse -Examples
5521
5522
5523
5524Let's close with a couple examples.
5525
5526@table @asis
5527
5528@item Average: 10, std dev: 1 Here the estimate would be
55292^10 = 1024 peers. (The range in which we can be 95% sure is:
5530[2^8, 2^12] = [256, 4096]. We can be very (>99.7%) sure that the network
5531is not a hundred peers and absolutely sure that it is not a million peers,
5532but somewhere around a thousand.)
5533
5534@item Average 22, std dev: 0.2 Here the estimate would be
55352^22 = 4 Million peers. (The range in which we can be 99.7% sure
5536is: [2^21.4, 2^22.6] = [2.8M, 6.3M]. We can be sure that the network size
5537is around four million, with absolutely way of it being 1 million.)
5538
5539@end table
5540
5541To put this in perspective, if someone remembers the LHC Higgs boson
5542results, were announced with "5 sigma" and "6 sigma" certainties. In this
5543case a 5 sigma minimum would be 2 million and a 6 sigma minimum,
55441.8 million.
5545
5546@node The NSE Client-Service Protocol
5547@subsection The NSE Client-Service Protocol
5548
5549
5550
5551As with the API, the client-service protocol is very simple, only has 2
5552different messages, defined in @code{src/nse/nse.h}:
5553
5554@itemize @bullet
5555@item @code{GNUNET_MESSAGE_TYPE_NSE_START}@ This message has no parameters
5556and is sent from the client to the service upon connection.
5557@item @code{GNUNET_MESSAGE_TYPE_NSE_ESTIMATE}@ This message is sent from
5558the service to the client for every new estimate and upon connection.
5559Contains a timestamp for the estimate, the average and the standard
5560deviation for the respective round.
5561@end itemize
5562
5563When the @code{GNUNET_NSE_disconnect} API call is executed, the client
5564simply disconnects from the service, with no message involved.
5565
5566@cindex NSE Peer-to-Peer Protocol
5567@node The NSE Peer-to-Peer Protocol
5568@subsection The NSE Peer-to-Peer Protocol
5569
5570
5571@pindex GNUNET_MESSAGE_TYPE_NSE_P2P_FLOOD
5572The NSE subsystem only has one message in the P2P protocol, the
5573@code{GNUNET_MESSAGE_TYPE_NSE_P2P_FLOOD} message.
5574
5575This message key contents are the timestamp to identify the round
5576(differences in system clocks may cause some peers to send messages way
5577too early or way too late, so the timestamp allows other peers to
5578identify such messages easily), the
5579@uref{http://en.wikipedia.org/wiki/Proof-of-work_system, proof of work}
5580used to make it difficult to mount a
5581@uref{http://en.wikipedia.org/wiki/Sybil_attack, Sybil attack}, and the
5582public key, which is used to verify the signature on the message.
5583
5584Every peer stores a message for the previous, current and next round. The
5585messages for the previous and current round are given to peers that
5586connect to us. The message for the next round is simply stored until our
5587system clock advances to the next round. The message for the current round
5588is what we are flooding the network with right now.
5589At the beginning of each round the peer does the following:
5590
5591@itemize @bullet
5592@item calculates its own distance to the target value
5593@item creates, signs and stores the message for the current round (unless
5594it has a better message in the "next round" slot which came early in the
5595previous round)
5596@item calculates, based on the stored round message (own or received) when
5597to start flooding it to its neighbors
5598@end itemize
5599
5600Upon receiving a message the peer checks the validity of the message
5601(round, proof of work, signature). The next action depends on the
5602contents of the incoming message:
5603
5604@itemize @bullet
5605@item if the message is worse than the current stored message, the peer
5606sends the current message back immediately, to stop the other peer from
5607spreading suboptimal results
5608@item if the message is better than the current stored message, the peer
5609stores the new message and calculates the new target time to start
5610spreading it to its neighbors (excluding the one the message came from)
5611@item if the message is for the previous round, it is compared to the
5612message stored in the "previous round slot", which may then be updated
5613@item if the message is for the next round, it is compared to the message
5614stored in the "next round slot", which again may then be updated
5615@end itemize
5616
5617Finally, when it comes to send the stored message for the current round to
5618the neighbors there is a random delay added for each neighbor, to avoid
5619traffic spikes and minimize cross-messages.
5620
5621@cindex HOSTLIST Subsystem
5622@node HOSTLIST Subsystem
5623@section HOSTLIST Subsystem
5624
5625
5626
5627Peers in the GNUnet overlay network need address information so that they
5628can connect with other peers. GNUnet uses so called HELLO messages to
5629store and exchange peer addresses.
5630GNUnet provides several methods for peers to obtain this information:
5631
5632@itemize @bullet
5633@item out-of-band exchange of HELLO messages (manually, using for example
5634gnunet-peerinfo)
5635@item HELLO messages shipped with GNUnet (automatic with distribution)
5636@item UDP neighbor discovery in LAN (IPv4 broadcast, IPv6 multicast)
5637@item topology gossiping (learning from other peers we already connected
5638to), and
5639@item the HOSTLIST daemon covered in this section, which is particularly
5640relevant for bootstrapping new peers.
5641@end itemize
5642
5643New peers have no existing connections (and thus cannot learn from gossip
5644among peers), may not have other peers in their LAN and might be started
5645with an outdated set of HELLO messages from the distribution.
5646In this case, getting new peers to connect to the network requires either
5647manual effort or the use of a HOSTLIST to obtain HELLOs.
5648
5649@menu
5650* HELLOs::
5651* Overview for the HOSTLIST subsystem::
5652* Interacting with the HOSTLIST daemon::
5653* Hostlist security address validation::
5654* The HOSTLIST daemon::
5655* The HOSTLIST server::
5656* The HOSTLIST client::
5657* Usage::
5658@end menu
5659
5660@node HELLOs
5661@subsection HELLOs
5662
5663
5664
5665The basic information peers require to connect to other peers are
5666contained in so called HELLO messages you can think of as a business card.
5667Besides the identity of the peer (based on the cryptographic public key) a
5668HELLO message may contain address information that specifies ways to
5669contact a peer. By obtaining HELLO messages, a peer can learn how to
5670contact other peers.
5671
5672@node Overview for the HOSTLIST subsystem
5673@subsection Overview for the HOSTLIST subsystem
5674
5675
5676
5677The HOSTLIST subsystem provides a way to distribute and obtain contact
5678information to connect to other peers using a simple HTTP GET request.
5679It's implementation is split in three parts, the main file for the daemon
5680itself (@file{gnunet-daemon-hostlist.c}), the HTTP client used to download
5681peer information (@file{hostlist-client.c}) and the server component used
5682to provide this information to other peers (@file{hostlist-server.c}).
5683The server is basically a small HTTP web server (based on GNU
5684libmicrohttpd) which provides a list of HELLOs known to the local peer for
5685download. The client component is basically a HTTP client
5686(based on libcurl) which can download hostlists from one or more websites.
5687The hostlist format is a binary blob containing a sequence of HELLO
5688messages. Note that any HTTP server can theoretically serve a hostlist,
5689the built-in hostlist server makes it simply convenient to offer this
5690service.
5691
5692
5693@menu
5694* Features::
5695* HOSTLIST - Limitations::
5696@end menu
5697
5698@node Features
5699@subsubsection Features
5700
5701
5702
5703The HOSTLIST daemon can:
5704
5705@itemize @bullet
5706@item provide HELLO messages with validated addresses obtained from
5707PEERINFO to download for other peers
5708@item download HELLO messages and forward these message to the TRANSPORT
5709subsystem for validation
5710@item advertises the URL of this peer's hostlist address to other peers
5711via gossip
5712@item automatically learn about hostlist servers from the gossip of other
5713peers
5714@end itemize
5715
5716@node HOSTLIST - Limitations
5717@subsubsection HOSTLIST - Limitations
5718
5719
5720
5721The HOSTLIST daemon does not:
5722
5723@itemize @bullet
5724@item verify the cryptographic information in the HELLO messages
5725@item verify the address information in the HELLO messages
5726@end itemize
5727
5728@node Interacting with the HOSTLIST daemon
5729@subsection Interacting with the HOSTLIST daemon
5730
5731
5732
5733The HOSTLIST subsystem is currently implemented as a daemon, so there is
5734no need for the user to interact with it and therefore there is no
5735command line tool and no API to communicate with the daemon. In the
5736future, we can envision changing this to allow users to manually trigger
5737the download of a hostlist.
5738
5739Since there is no command line interface to interact with HOSTLIST, the
5740only way to interact with the hostlist is to use STATISTICS to obtain or
5741modify information about the status of HOSTLIST:
5742
5743@example
5744$ gnunet-statistics -s hostlist
5745@end example
5746
5747@noindent
5748In particular, HOSTLIST includes a @strong{persistent} value in statistics
5749that specifies when the hostlist server might be queried next. As this
5750value is exponentially increasing during runtime, developers may want to
5751reset or manually adjust it. Note that HOSTLIST (but not STATISTICS) needs
5752to be shutdown if changes to this value are to have any effect on the
5753daemon (as HOSTLIST does not monitor STATISTICS for changes to the
5754download frequency).
5755
5756@node Hostlist security address validation
5757@subsection Hostlist security address validation
5758
5759
5760
5761Since information obtained from other parties cannot be trusted without
5762validation, we have to distinguish between @emph{validated} and
5763@emph{not validated} addresses. Before using (and so trusting)
5764information from other parties, this information has to be double-checked
5765(validated). Address validation is not done by HOSTLIST but by the
5766TRANSPORT service.
5767
5768The HOSTLIST component is functionally located between the PEERINFO and
5769the TRANSPORT subsystem. When acting as a server, the daemon obtains valid
5770(@emph{validated}) peer information (HELLO messages) from the PEERINFO
5771service and provides it to other peers. When acting as a client, it
5772contacts the HOSTLIST servers specified in the configuration, downloads
5773the (unvalidated) list of HELLO messages and forwards these information
5774to the TRANSPORT server to validate the addresses.
5775
5776@cindex HOSTLIST daemon
5777@node The HOSTLIST daemon
5778@subsection The HOSTLIST daemon
5779
5780
5781
5782The hostlist daemon is the main component of the HOSTLIST subsystem. It is
5783started by the ARM service and (if configured) starts the HOSTLIST client
5784and server components.
5785
5786@pindex GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT
5787If the daemon provides a hostlist itself it can advertise it's own
5788hostlist to other peers. To do so it sends a
5789@code{GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT} message to other peers
5790when they connect to this peer on the CORE level. This hostlist
5791advertisement message contains the URL to access the HOSTLIST HTTP
5792server of the sender. The daemon may also subscribe to this type of
5793message from CORE service, and then forward these kind of message to the
5794HOSTLIST client. The client then uses all available URLs to download peer
5795information when necessary.
5796
5797When starting, the HOSTLIST daemon first connects to the CORE subsystem
5798and if hostlist learning is enabled, registers a CORE handler to receive
5799this kind of messages. Next it starts (if configured) the client and
5800server. It passes pointers to CORE connect and disconnect and receive
5801handlers where the client and server store their functions, so the daemon
5802can notify them about CORE events.
5803
5804To clean up on shutdown, the daemon has a cleaning task, shutting down all
5805subsystems and disconnecting from CORE.
5806
5807@cindex HOSTLIST server
5808@node The HOSTLIST server
5809@subsection The HOSTLIST server
5810
5811
5812
5813The server provides a way for other peers to obtain HELLOs. Basically it
5814is a small web server other peers can connect to and download a list of
5815HELLOs using standard HTTP; it may also advertise the URL of the hostlist
5816to other peers connecting on CORE level.
5817
5818
5819@menu
5820* The HTTP Server::
5821* Advertising the URL::
5822@end menu
5823
5824@node The HTTP Server
5825@subsubsection The HTTP Server
5826
5827
5828
5829During startup, the server starts a web server listening on the port
5830specified with the HTTPPORT value (default 8080). In addition it connects
5831to the PEERINFO service to obtain peer information. The HOSTLIST server
5832uses the GNUNET_PEERINFO_iterate function to request HELLO information for
5833all peers and adds their information to a new hostlist if they are
5834suitable (expired addresses and HELLOs without addresses are both not
5835suitable) and the maximum size for a hostlist is not exceeded
5836(MAX_BYTES_PER_HOSTLISTS = 500000).
5837When PEERINFO finishes (with a last NULL callback), the server destroys
5838the previous hostlist response available for download on the web server
5839and replaces it with the updated hostlist. The hostlist format is
5840basically a sequence of HELLO messages (as obtained from PEERINFO) without
5841any special tokenization. Since each HELLO message contains a size field,
5842the response can easily be split into separate HELLO messages by the
5843client.
5844
5845A HOSTLIST client connecting to the HOSTLIST server will receive the
5846hostlist as an HTTP response and the server will terminate the
5847connection with the result code @code{HTTP 200 OK}.
5848The connection will be closed immediately if no hostlist is available.
5849
5850@node Advertising the URL
5851@subsubsection Advertising the URL
5852
5853
5854
5855The server also advertises the URL to download the hostlist to other peers
5856if hostlist advertisement is enabled.
5857When a new peer connects and has hostlist learning enabled, the server
5858sends a @code{GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT} message to this
5859peer using the CORE service.
5860
5861@cindex HOSTLIST client
5862@node The HOSTLIST client
5863@subsection The HOSTLIST client
5864
5865
5866
5867The client provides the functionality to download the list of HELLOs from
5868a set of URLs.
5869It performs a standard HTTP request to the URLs configured and learned
5870from advertisement messages received from other peers. When a HELLO is
5871downloaded, the HOSTLIST client forwards the HELLO to the TRANSPORT
5872service for validation.
5873
5874The client supports two modes of operation:
5875
5876@itemize @bullet
5877@item download of HELLOs (bootstrapping)
5878@item learning of URLs
5879@end itemize
5880
5881@menu
5882* Bootstrapping::
5883* Learning::
5884@end menu
5885
5886@node Bootstrapping
5887@subsubsection Bootstrapping
5888
5889
5890
5891For bootstrapping, it schedules a task to download the hostlist from the
5892set of known URLs.
5893The downloads are only performed if the number of current
5894connections is smaller than a minimum number of connections
5895(at the moment 4).
5896The interval between downloads increases exponentially; however, the
5897exponential growth is limited if it becomes longer than an hour.
5898At that point, the frequency growth is capped at
5899(#number of connections * 1h).
5900
5901Once the decision has been taken to download HELLOs, the daemon chooses a
5902random URL from the list of known URLs. URLs can be configured in the
5903configuration or be learned from advertisement messages.
5904The client uses a HTTP client library (libcurl) to initiate the download
5905using the libcurl multi interface.
5906Libcurl passes the data to the callback_download function which
5907stores the data in a buffer if space is available and the maximum size for
5908a hostlist download is not exceeded (MAX_BYTES_PER_HOSTLISTS = 500000).
5909When a full HELLO was downloaded, the HOSTLIST client offers this
5910HELLO message to the TRANSPORT service for validation.
5911When the download is finished or failed, statistical information about the
5912quality of this URL is updated.
5913
5914@cindex HOSTLIST learning
5915@node Learning
5916@subsubsection Learning
5917
5918
5919
5920The client also manages hostlist advertisements from other peers. The
5921HOSTLIST daemon forwards @code{GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT}
5922messages to the client subsystem, which extracts the URL from the message.
5923Next, a test of the newly obtained URL is performed by triggering a
5924download from the new URL. If the URL works correctly, it is added to the
5925list of working URLs.
5926
5927The size of the list of URLs is restricted, so if an additional server is
5928added and the list is full, the URL with the worst quality ranking
5929(determined through successful downloads and number of HELLOs e.g.) is
5930discarded. During shutdown the list of URLs is saved to a file for
5931persistence and loaded on startup. URLs from the configuration file are
5932never discarded.
5933
5934@node Usage
5935@subsection Usage
5936
5937
5938
5939To start HOSTLIST by default, it has to be added to the DEFAULTSERVICES
5940section for the ARM services. This is done in the default configuration.
5941
5942For more information on how to configure the HOSTLIST subsystem see the
5943installation handbook:@
5944Configuring the hostlist to bootstrap@
5945Configuring your peer to provide a hostlist
5946
5947@cindex IDENTITY Subsystem
5948@node IDENTITY Subsystem
5949@section IDENTITY Subsystem
5950
5951
5952
5953Identities of "users" in GNUnet are called egos.
5954Egos can be used as pseudonyms ("fake names") or be tied to an
5955organization (for example, "GNU") or even the actual identity of a human.
5956GNUnet users are expected to have many egos. They might have one tied to
5957their real identity, some for organizations they manage, and more for
5958different domains where they want to operate under a pseudonym.
5959
5960The IDENTITY service allows users to manage their egos. The identity
5961service manages the private keys egos of the local user; it does not
5962manage identities of other users (public keys). Public keys for other
5963users need names to become manageable. GNUnet uses the
5964@dfn{GNU Name System} (GNS) to give names to other users and manage their
5965public keys securely. This chapter is about the IDENTITY service,
5966which is about the management of private keys.
5967
5968On the network, an ego corresponds to an ECDSA key (over Curve25519,
5969using RFC 6979, as required by GNS). Thus, users can perform actions
5970under a particular ego by using (signing with) a particular private key.
5971Other users can then confirm that the action was really performed by that
5972ego by checking the signature against the respective public key.
5973
5974The IDENTITY service allows users to associate a human-readable name with
5975each ego. This way, users can use names that will remind them of the
5976purpose of a particular ego.
5977The IDENTITY service will store the respective private keys and
5978allows applications to access key information by name.
5979Users can change the name that is locally (!) associated with an ego.
5980Egos can also be deleted, which means that the private key will be removed
5981and it thus will not be possible to perform actions with that ego in the
5982future.
5983
5984Additionally, the IDENTITY subsystem can associate service functions with
5985egos.
5986For example, GNS requires the ego that should be used for the shorten
5987zone. GNS will ask IDENTITY for an ego for the "gns-short" service.
5988The IDENTITY service has a mapping of such service strings to the name of
5989the ego that the user wants to use for this service, for example
5990"my-short-zone-ego".
5991
5992Finally, the IDENTITY API provides access to a special ego, the
5993anonymous ego. The anonymous ego is special in that its private key is not
5994really private, but fixed and known to everyone.
5995Thus, anyone can perform actions as anonymous. This can be useful as with
5996this trick, code does not have to contain a special case to distinguish
5997between anonymous and pseudonymous egos.
5998
5999@menu
6000* libgnunetidentity::
6001* The IDENTITY Client-Service Protocol::
6002@end menu
6003
6004@cindex libgnunetidentity
6005@node libgnunetidentity
6006@subsection libgnunetidentity
6007
6008
6009
6010@menu
6011* Connecting to the service::
6012* Operations on Egos::
6013* The anonymous Ego::
6014* Convenience API to lookup a single ego::
6015* Associating egos with service functions::
6016@end menu
6017
6018@node Connecting to the service
6019@subsubsection Connecting to the service
6020
6021
6022
6023First, typical clients connect to the identity service using
6024@code{GNUNET_IDENTITY_connect}. This function takes a callback as a
6025parameter.
6026If the given callback parameter is non-null, it will be invoked to notify
6027the application about the current state of the identities in the system.
6028
6029@itemize @bullet
6030@item First, it will be invoked on all known egos at the time of the
6031connection. For each ego, a handle to the ego and the user's name for the
6032ego will be passed to the callback. Furthermore, a @code{void **} context
6033argument will be provided which gives the client the opportunity to
6034associate some state with the ego.
6035@item Second, the callback will be invoked with NULL for the ego, the name
6036and the context. This signals that the (initial) iteration over all egos
6037has completed.
6038@item Then, the callback will be invoked whenever something changes about
6039an ego.
6040If an ego is renamed, the callback is invoked with the ego handle of the
6041ego that was renamed, and the new name. If an ego is deleted, the callback
6042is invoked with the ego handle and a name of NULL. In the deletion case,
6043the application should also release resources stored in the context.
6044@item When the application destroys the connection to the identity service
6045using @code{GNUNET_IDENTITY_disconnect}, the callback is again invoked
6046with the ego and a name of NULL (equivalent to deletion of the egos).
6047This should again be used to clean up the per-ego context.
6048@end itemize
6049
6050The ego handle passed to the callback remains valid until the callback is
6051invoked with a name of NULL, so it is safe to store a reference to the
6052ego's handle.
6053
6054@node Operations on Egos
6055@subsubsection Operations on Egos
6056
6057
6058
6059Given an ego handle, the main operations are to get its associated private
6060key using @code{GNUNET_IDENTITY_ego_get_private_key} or its associated
6061public key using @code{GNUNET_IDENTITY_ego_get_public_key}.
6062
6063The other operations on egos are pretty straightforward.
6064Using @code{GNUNET_IDENTITY_create}, an application can request the
6065creation of an ego by specifying the desired name.
6066The operation will fail if that name is
6067already in use. Using @code{GNUNET_IDENTITY_rename} the name of an
6068existing ego can be changed. Finally, egos can be deleted using
6069@code{GNUNET_IDENTITY_delete}. All of these operations will trigger
6070updates to the callback given to the @code{GNUNET_IDENTITY_connect}
6071function of all applications that are connected with the identity service
6072at the time. @code{GNUNET_IDENTITY_cancel} can be used to cancel the
6073operations before the respective continuations would be called.
6074It is not guaranteed that the operation will not be completed anyway,
6075only the continuation will no longer be called.
6076
6077@node The anonymous Ego
6078@subsubsection The anonymous Ego
6079
6080
6081
6082A special way to obtain an ego handle is to call
6083@code{GNUNET_IDENTITY_ego_get_anonymous}, which returns an ego for the
6084"anonymous" user --- anyone knows and can get the private key for this
6085user, so it is suitable for operations that are supposed to be anonymous
6086but require signatures (for example, to avoid a special path in the code).
6087The anonymous ego is always valid and accessing it does not require a
6088connection to the identity service.
6089
6090@node Convenience API to lookup a single ego
6091@subsubsection Convenience API to lookup a single ego
6092
6093
6094As applications commonly simply have to lookup a single ego, there is a
6095convenience API to do just that. Use @code{GNUNET_IDENTITY_ego_lookup} to
6096lookup a single ego by name. Note that this is the user's name for the
6097ego, not the service function. The resulting ego will be returned via a
6098callback and will only be valid during that callback. The operation can
6099be canceled via @code{GNUNET_IDENTITY_ego_lookup_cancel}
6100(cancellation is only legal before the callback is invoked).
6101
6102@node Associating egos with service functions
6103@subsubsection Associating egos with service functions
6104
6105
6106The @code{GNUNET_IDENTITY_set} function is used to associate a particular
6107ego with a service function. The name used by the service and the ego are
6108given as arguments.
6109Afterwards, the service can use its name to lookup the associated ego
6110using @code{GNUNET_IDENTITY_get}.
6111
6112@node The IDENTITY Client-Service Protocol
6113@subsection The IDENTITY Client-Service Protocol
6114
6115
6116
6117A client connecting to the identity service first sends a message with
6118type
6119@code{GNUNET_MESSAGE_TYPE_IDENTITY_START} to the service. After that, the
6120client will receive information about changes to the egos by receiving
6121messages of type @code{GNUNET_MESSAGE_TYPE_IDENTITY_UPDATE}.
6122Those messages contain the private key of the ego and the user's name of
6123the ego (or zero bytes for the name to indicate that the ego was deleted).
6124A special bit @code{end_of_list} is used to indicate the end of the
6125initial iteration over the identity service's egos.
6126
6127The client can trigger changes to the egos by sending @code{CREATE},
6128@code{RENAME} or @code{DELETE} messages.
6129The CREATE message contains the private key and the desired name.@
6130The RENAME message contains the old name and the new name.@
6131The DELETE message only needs to include the name of the ego to delete.@
6132The service responds to each of these messages with a @code{RESULT_CODE}
6133message which indicates success or error of the operation, and possibly
6134a human-readable error message.
6135
6136Finally, the client can bind the name of a service function to an ego by
6137sending a @code{SET_DEFAULT} message with the name of the service function
6138and the private key of the ego.
6139Such bindings can then be resolved using a @code{GET_DEFAULT} message,
6140which includes the name of the service function. The identity service
6141will respond to a GET_DEFAULT request with a SET_DEFAULT message
6142containing the respective information, or with a RESULT_CODE to
6143indicate an error.
6144
6145@cindex NAMESTORE Subsystem
6146@node NAMESTORE Subsystem
6147@section NAMESTORE Subsystem
6148
6149The NAMESTORE subsystem provides persistent storage for local GNS zone
6150information. All local GNS zone information are managed by NAMESTORE. It
6151provides both the functionality to administer local GNS information (e.g.
6152delete and add records) as well as to retrieve GNS information (e.g to
6153list name information in a client).
6154NAMESTORE does only manage the persistent storage of zone information
6155belonging to the user running the service: GNS information from other
6156users obtained from the DHT are stored by the NAMECACHE subsystem.
6157
6158NAMESTORE uses a plugin-based database backend to store GNS information
6159with good performance. Here sqlite, MySQL and PostgreSQL are supported
6160database backends.
6161NAMESTORE clients interact with the IDENTITY subsystem to obtain
6162cryptographic information about zones based on egos as described with the
6163IDENTITY subsystem, but internally NAMESTORE refers to zones using the
6164ECDSA private key.
6165In addition, it collaborates with the NAMECACHE subsystem and
6166stores zone information when local information are modified in the
6167GNS cache to increase look-up performance for local information.
6168
6169NAMESTORE provides functionality to look-up and store records, to iterate
6170over a specific or all zones and to monitor zones for changes. NAMESTORE
6171functionality can be accessed using the NAMESTORE api or the NAMESTORE
6172command line tool.
6173
6174@menu
6175* libgnunetnamestore::
6176@end menu
6177
6178@cindex libgnunetnamestore
6179@node libgnunetnamestore
6180@subsection libgnunetnamestore
6181
6182To interact with NAMESTORE clients first connect to the NAMESTORE service
6183using the @code{GNUNET_NAMESTORE_connect} passing a configuration handle.
6184As a result they obtain a NAMESTORE handle, they can use for operations,
6185or NULL is returned if the connection failed.
6186
6187To disconnect from NAMESTORE, clients use
6188@code{GNUNET_NAMESTORE_disconnect} and specify the handle to disconnect.
6189
6190NAMESTORE internally uses the ECDSA private key to refer to zones. These
6191private keys can be obtained from the IDENTITY subsystem.
6192Here @emph{egos} @emph{can be used to refer to zones or the default ego
6193assigned to the GNS subsystem can be used to obtained the master zone's
6194private key.}
6195
6196
6197@menu
6198* Editing Zone Information::
6199* Iterating Zone Information::
6200* Monitoring Zone Information::
6201@end menu
6202
6203@node Editing Zone Information
6204@subsubsection Editing Zone Information
6205
6206
6207
6208NAMESTORE provides functions to lookup records stored under a label in a
6209zone and to store records under a label in a zone.
6210
6211To store (and delete) records, the client uses the
6212@code{GNUNET_NAMESTORE_records_store} function and has to provide
6213namestore handle to use, the private key of the zone, the label to store
6214the records under, the records and number of records plus an callback
6215function.
6216After the operation is performed NAMESTORE will call the provided
6217callback function with the result GNUNET_SYSERR on failure
6218(including timeout/queue drop/failure to validate), GNUNET_NO if content
6219was already there or not found GNUNET_YES (or other positive value) on
6220success plus an additional error message.
6221
6222Records are deleted by using the store command with 0 records to store.
6223It is important to note, that records are not merged when records exist
6224with the label.
6225So a client has first to retrieve records, merge with existing records
6226and then store the result.
6227
6228To perform a lookup operation, the client uses the
6229@code{GNUNET_NAMESTORE_records_store} function. Here it has to pass the
6230namestore handle, the private key of the zone and the label. It also has
6231to provide a callback function which will be called with the result of
6232the lookup operation:
6233the zone for the records, the label, and the records including the
6234number of records included.
6235
6236A special operation is used to set the preferred nickname for a zone.
6237This nickname is stored with the zone and is automatically merged with
6238all labels and records stored in a zone. Here the client uses the
6239@code{GNUNET_NAMESTORE_set_nick} function and passes the private key of
6240the zone, the nickname as string plus a the callback with the result of
6241the operation.
6242
6243@node Iterating Zone Information
6244@subsubsection Iterating Zone Information
6245
6246
6247
6248A client can iterate over all information in a zone or all zones managed
6249by NAMESTORE.
6250Here a client uses the @code{GNUNET_NAMESTORE_zone_iteration_start}
6251function and passes the namestore handle, the zone to iterate over and a
6252callback function to call with the result.
6253If the client wants to iterate over all the WHAT!? FIXME, it passes NULL for the zone.
6254A @code{GNUNET_NAMESTORE_ZoneIterator} handle is returned to be used to
6255continue iteration.
6256
6257NAMESTORE calls the callback for every result and expects the client to
6258call @code{GNUNET_NAMESTORE_zone_iterator_next} to continue to iterate or
6259@code{GNUNET_NAMESTORE_zone_iterator_stop} to interrupt the iteration.
6260When NAMESTORE reached the last item it will call the callback with a
6261NULL value to indicate.
6262
6263@node Monitoring Zone Information
6264@subsubsection Monitoring Zone Information
6265
6266
6267
6268Clients can also monitor zones to be notified about changes. Here the
6269clients uses the @code{GNUNET_NAMESTORE_zone_monitor_start} function and
6270passes the private key of the zone and and a callback function to call
6271with updates for a zone.
6272The client can specify to obtain zone information first by iterating over
6273the zone and specify a synchronization callback to be called when the
6274client and the namestore are synced.
6275
6276On an update, NAMESTORE will call the callback with the private key of the
6277zone, the label and the records and their number.
6278
6279To stop monitoring, the client calls
6280@code{GNUNET_NAMESTORE_zone_monitor_stop} and passes the handle obtained
6281from the function to start the monitoring.
6282
6283@cindex PEERINFO Subsystem
6284@node PEERINFO Subsystem
6285@section PEERINFO Subsystem
6286
6287
6288
6289The PEERINFO subsystem is used to store verified (validated) information
6290about known peers in a persistent way. It obtains these addresses for
6291example from TRANSPORT service which is in charge of address validation.
6292Validation means that the information in the HELLO message are checked by
6293connecting to the addresses and performing a cryptographic handshake to
6294authenticate the peer instance stating to be reachable with these
6295addresses.
6296Peerinfo does not validate the HELLO messages itself but only stores them
6297and gives them to interested clients.
6298
6299As future work, we think about moving from storing just HELLO messages to
6300providing a generic persistent per-peer information store.
6301More and more subsystems tend to need to store per-peer information in
6302persistent way.
6303To not duplicate this functionality we plan to provide a PEERSTORE
6304service providing this functionality.
6305
6306@menu
6307* PEERINFO - Features::
6308* PEERINFO - Limitations::
6309* DeveloperPeer Information::
6310* Startup::
6311* Managing Information::
6312* Obtaining Information::
6313* The PEERINFO Client-Service Protocol::
6314* libgnunetpeerinfo::
6315@end menu
6316
6317@node PEERINFO - Features
6318@subsection PEERINFO - Features
6319
6320
6321
6322@itemize @bullet
6323@item Persistent storage
6324@item Client notification mechanism on update
6325@item Periodic clean up for expired information
6326@item Differentiation between public and friend-only HELLO
6327@end itemize
6328
6329@node PEERINFO - Limitations
6330@subsection PEERINFO - Limitations
6331
6332
6333@itemize @bullet
6334@item Does not perform HELLO validation
6335@end itemize
6336
6337@node DeveloperPeer Information
6338@subsection DeveloperPeer Information
6339
6340
6341
6342The PEERINFO subsystem stores these information in the form of HELLO
6343messages you can think of as business cards.
6344These HELLO messages contain the public key of a peer and the addresses
6345a peer can be reached under.
6346The addresses include an expiration date describing how long they are
6347valid. This information is updated regularly by the TRANSPORT service by
6348revalidating the address.
6349If an address is expired and not renewed, it can be removed from the
6350HELLO message.
6351
6352Some peer do not want to have their HELLO messages distributed to other
6353peers, especially when GNUnet's friend-to-friend modus is enabled.
6354To prevent this undesired distribution. PEERINFO distinguishes between
6355@emph{public} and @emph{friend-only} HELLO messages.
6356Public HELLO messages can be freely distributed to other (possibly
6357unknown) peers (for example using the hostlist, gossiping, broadcasting),
6358whereas friend-only HELLO messages may not be distributed to other peers.
6359Friend-only HELLO messages have an additional flag @code{friend_only} set
6360internally. For public HELLO message this flag is not set.
6361PEERINFO does and cannot not check if a client is allowed to obtain a
6362specific HELLO type.
6363
6364The HELLO messages can be managed using the GNUnet HELLO library.
6365Other GNUnet systems can obtain these information from PEERINFO and use
6366it for their purposes.
6367Clients are for example the HOSTLIST component providing these
6368information to other peers in form of a hostlist or the TRANSPORT
6369subsystem using these information to maintain connections to other peers.
6370
6371@node Startup
6372@subsection Startup
6373
6374
6375
6376During startup the PEERINFO services loads persistent HELLOs from disk.
6377First PEERINFO parses the directory configured in the HOSTS value of the
6378@code{PEERINFO} configuration section to store PEERINFO information.
6379For all files found in this directory valid HELLO messages are extracted.
6380In addition it loads HELLO messages shipped with the GNUnet distribution.
6381These HELLOs are used to simplify network bootstrapping by providing
6382valid peer information with the distribution.
6383The use of these HELLOs can be prevented by setting the
6384@code{USE_INCLUDED_HELLOS} in the @code{PEERINFO} configuration section to
6385@code{NO}. Files containing invalid information are removed.
6386
6387@node Managing Information
6388@subsection Managing Information
6389
6390
6391
6392The PEERINFO services stores information about known PEERS and a single
6393HELLO message for every peer.
6394A peer does not need to have a HELLO if no information are available.
6395HELLO information from different sources, for example a HELLO obtained
6396from a remote HOSTLIST and a second HELLO stored on disk, are combined
6397and merged into one single HELLO message per peer which will be given to
6398clients. During this merge process the HELLO is immediately written to
6399disk to ensure persistence.
6400
6401PEERINFO in addition periodically scans the directory where information
6402are stored for empty HELLO messages with expired TRANSPORT addresses.
6403This periodic task scans all files in the directory and recreates the
6404HELLO messages it finds.
6405Expired TRANSPORT addresses are removed from the HELLO and if the
6406HELLO does not contain any valid addresses, it is discarded and removed
6407from the disk.
6408
6409@node Obtaining Information
6410@subsection Obtaining Information
6411
6412
6413
6414When a client requests information from PEERINFO, PEERINFO performs a
6415lookup for the respective peer or all peers if desired and transmits this
6416information to the client.
6417The client can specify if friend-only HELLOs have to be included or not
6418and PEERINFO filters the respective HELLO messages before transmitting
6419information.
6420
6421To notify clients about changes to PEERINFO information, PEERINFO
6422maintains a list of clients interested in this notifications.
6423Such a notification occurs if a HELLO for a peer was updated (due to a
6424merge for example) or a new peer was added.
6425
6426@node The PEERINFO Client-Service Protocol
6427@subsection The PEERINFO Client-Service Protocol
6428
6429
6430
6431To connect and disconnect to and from the PEERINFO Service PEERINFO
6432utilizes the util client/server infrastructure, so no special messages
6433types are used here.
6434
6435To add information for a peer, the plain HELLO message is transmitted to
6436the service without any wrapping. All pieces of information required are
6437stored within the HELLO message.
6438The PEERINFO service provides a message handler accepting and processing
6439these HELLO messages.
6440
6441When obtaining PEERINFO information using the iterate functionality
6442specific messages are used. To obtain information for all peers, a
6443@code{struct ListAllPeersMessage} with message type
6444@code{GNUNET_MESSAGE_TYPE_PEERINFO_GET_ALL} and a flag
6445include_friend_only to indicate if friend-only HELLO messages should be
6446included are transmitted. If information for a specific peer is required
6447a @code{struct ListAllPeersMessage} with
6448@code{GNUNET_MESSAGE_TYPE_PEERINFO_GET} containing the peer identity is
6449used.
6450
6451For both variants the PEERINFO service replies for each HELLO message it
6452wants to transmit with a @code{struct ListAllPeersMessage} with type
6453@code{GNUNET_MESSAGE_TYPE_PEERINFO_INFO} containing the plain HELLO.
6454The final message is @code{struct GNUNET_MessageHeader} with type
6455@code{GNUNET_MESSAGE_TYPE_PEERINFO_INFO}. If the client receives this
6456message, it can proceed with the next request if any is pending.
6457
6458@node libgnunetpeerinfo
6459@subsection libgnunetpeerinfo
6460
6461
6462
6463The PEERINFO API consists mainly of three different functionalities:
6464
6465@itemize @bullet
6466@item maintaining a connection to the service
6467@item adding new information to the PEERINFO service
6468@item retrieving information from the PEERINFO service
6469@end itemize
6470
6471@menu
6472* Connecting to the PEERINFO Service::
6473* Adding Information to the PEERINFO Service::
6474* Obtaining Information from the PEERINFO Service::
6475@end menu
6476
6477@node Connecting to the PEERINFO Service
6478@subsubsection Connecting to the PEERINFO Service
6479
6480
6481
6482To connect to the PEERINFO service the function
6483@code{GNUNET_PEERINFO_connect} is used, taking a configuration handle as
6484an argument, and to disconnect from PEERINFO the function
6485@code{GNUNET_PEERINFO_disconnect}, taking the PEERINFO
6486handle returned from the connect function has to be called.
6487
6488@node Adding Information to the PEERINFO Service
6489@subsubsection Adding Information to the PEERINFO Service
6490
6491
6492
6493@code{GNUNET_PEERINFO_add_peer} adds a new peer to the PEERINFO subsystem
6494storage. This function takes the PEERINFO handle as an argument, the HELLO
6495message to store and a continuation with a closure to be called with the
6496result of the operation.
6497The @code{GNUNET_PEERINFO_add_peer} returns a handle to this operation
6498allowing to cancel the operation with the respective cancel function
6499@code{GNUNET_PEERINFO_add_peer_cancel}. To retrieve information from
6500PEERINFO you can iterate over all information stored with PEERINFO or you
6501can tell PEERINFO to notify if new peer information are available.
6502
6503@node Obtaining Information from the PEERINFO Service
6504@subsubsection Obtaining Information from the PEERINFO Service
6505
6506
6507
6508To iterate over information in PEERINFO you use
6509@code{GNUNET_PEERINFO_iterate}.
6510This function expects the PEERINFO handle, a flag if HELLO messages
6511intended for friend only mode should be included, a timeout how long the
6512operation should take and a callback with a callback closure to be called
6513for the results.
6514If you want to obtain information for a specific peer, you can specify
6515the peer identity, if this identity is NULL, information for all peers are
6516returned. The function returns a handle to allow to cancel the operation
6517using @code{GNUNET_PEERINFO_iterate_cancel}.
6518
6519To get notified when peer information changes, you can use
6520@code{GNUNET_PEERINFO_notify}.
6521This function expects a configuration handle and a flag if friend-only
6522HELLO messages should be included. The PEERINFO service will notify you
6523about every change and the callback function will be called to notify you
6524about changes. The function returns a handle to cancel notifications
6525with @code{GNUNET_PEERINFO_notify_cancel}.
6526
6527@cindex PEERSTORE Subsystem
6528@node PEERSTORE Subsystem
6529@section PEERSTORE Subsystem
6530
6531
6532
6533GNUnet's PEERSTORE subsystem offers persistent per-peer storage for other
6534GNUnet subsystems. GNUnet subsystems can use PEERSTORE to persistently
6535store and retrieve arbitrary data.
6536Each data record stored with PEERSTORE contains the following fields:
6537
6538@itemize @bullet
6539@item subsystem: Name of the subsystem responsible for the record.
6540@item peerid: Identity of the peer this record is related to.
6541@item key: a key string identifying the record.
6542@item value: binary record value.
6543@item expiry: record expiry date.
6544@end itemize
6545
6546@menu
6547* Functionality::
6548* Architecture::
6549* libgnunetpeerstore::
6550@end menu
6551
6552@node Functionality
6553@subsection Functionality
6554
6555
6556
6557Subsystems can store any type of value under a (subsystem, peerid, key)
6558combination. A "replace" flag set during store operations forces the
6559PEERSTORE to replace any old values stored under the same
6560(subsystem, peerid, key) combination with the new value.
6561Additionally, an expiry date is set after which the record is *possibly*
6562deleted by PEERSTORE.
6563
6564Subsystems can iterate over all values stored under any of the following
6565combination of fields:
6566
6567@itemize @bullet
6568@item (subsystem)
6569@item (subsystem, peerid)
6570@item (subsystem, key)
6571@item (subsystem, peerid, key)
6572@end itemize
6573
6574Subsystems can also request to be notified about any new values stored
6575under a (subsystem, peerid, key) combination by sending a "watch"
6576request to PEERSTORE.
6577
6578@node Architecture
6579@subsection Architecture
6580
6581
6582
6583PEERSTORE implements the following components:
6584
6585@itemize @bullet
6586@item PEERSTORE service: Handles store, iterate and watch operations.
6587@item PEERSTORE API: API to be used by other subsystems to communicate and
6588issue commands to the PEERSTORE service.
6589@item PEERSTORE plugins: Handles the persistent storage. At the moment,
6590only an "sqlite" plugin is implemented.
6591@end itemize
6592
6593@cindex libgnunetpeerstore
6594@node libgnunetpeerstore
6595@subsection libgnunetpeerstore
6596
6597
6598
6599libgnunetpeerstore is the library containing the PEERSTORE API. Subsystems
6600wishing to communicate with the PEERSTORE service use this API to open a
6601connection to PEERSTORE. This is done by calling
6602@code{GNUNET_PEERSTORE_connect} which returns a handle to the newly
6603created connection.
6604This handle has to be used with any further calls to the API.
6605
6606To store a new record, the function @code{GNUNET_PEERSTORE_store} is to
6607be used which requires the record fields and a continuation function that
6608will be called by the API after the STORE request is sent to the
6609PEERSTORE service.
6610Note that calling the continuation function does not mean that the record
6611is successfully stored, only that the STORE request has been successfully
6612sent to the PEERSTORE service.
6613@code{GNUNET_PEERSTORE_store_cancel} can be called to cancel the STORE
6614request only before the continuation function has been called.
6615
6616To iterate over stored records, the function
6617@code{GNUNET_PEERSTORE_iterate} is
6618to be used. @emph{peerid} and @emph{key} can be set to NULL. An iterator
6619callback function will be called with each matching record found and a
6620NULL record at the end to signal the end of result set.
6621@code{GNUNET_PEERSTORE_iterate_cancel} can be used to cancel the ITERATE
6622request before the iterator callback is called with a NULL record.
6623
6624To be notified with new values stored under a (subsystem, peerid, key)
6625combination, the function @code{GNUNET_PEERSTORE_watch} is to be used.
6626This will register the watcher with the PEERSTORE service, any new
6627records matching the given combination will trigger the callback
6628function passed to @code{GNUNET_PEERSTORE_watch}. This continues until
6629@code{GNUNET_PEERSTORE_watch_cancel} is called or the connection to the
6630service is destroyed.
6631
6632After the connection is no longer needed, the function
6633@code{GNUNET_PEERSTORE_disconnect} can be called to disconnect from the
6634PEERSTORE service.
6635Any pending ITERATE or WATCH requests will be destroyed.
6636If the @code{sync_first} flag is set to @code{GNUNET_YES}, the API will
6637delay the disconnection until all pending STORE requests are sent to
6638the PEERSTORE service, otherwise, the pending STORE requests will be
6639destroyed as well.
6640
6641@cindex SET Subsystem
6642@node SET Subsystem
6643@section SET Subsystem
6644
6645The SET subsystem is in process of being replaced by the SETU and
6646SETI subsystems, which provide basically the same functionality,
6647just using two different subsystems. SETI and SETU should be used
6648for new code.
6649
6650The SET service implements efficient set operations between two peers
6651over a CADET tunnel.
6652Currently, set union and set intersection are the only supported
6653operations. Elements of a set consist of an @emph{element type} and
6654arbitrary binary @emph{data}.
6655The size of an element's data is limited to around 62 KB.
6656
6657@menu
6658* Local Sets::
6659* Set Modifications::
6660* Set Operations::
6661* Result Elements::
6662* libgnunetset::
6663* The SET Client-Service Protocol::
6664* The SET Intersection Peer-to-Peer Protocol::
6665* The SET Union Peer-to-Peer Protocol::
6666@end menu
6667
6668@node Local Sets
6669@subsection Local Sets
6670
6671
6672
6673Sets created by a local client can be modified and reused for multiple
6674operations. As each set operation requires potentially expensive special
6675auxiliary data to be computed for each element of a set, a set can only
6676participate in one type of set operation (either union or intersection).
6677The type of a set is determined upon its creation.
6678If a the elements of a set are needed for an operation of a different
6679type, all of the set's element must be copied to a new set of appropriate
6680type.
6681
6682@node Set Modifications
6683@subsection Set Modifications
6684
6685
6686
6687Even when set operations are active, one can add to and remove elements
6688from a set.
6689However, these changes will only be visible to operations that have been
6690created after the changes have taken place. That is, every set operation
6691only sees a snapshot of the set from the time the operation was started.
6692This mechanism is @emph{not} implemented by copying the whole set, but by
6693attaching @emph{generation information} to each element and operation.
6694
6695@node Set Operations
6696@subsection Set Operations
6697
6698
6699
6700Set operations can be started in two ways: Either by accepting an
6701operation request from a remote peer, or by requesting a set operation
6702from a remote peer.
6703Set operations are uniquely identified by the involved @emph{peers}, an
6704@emph{application id} and the @emph{operation type}.
6705
6706The client is notified of incoming set operations by @emph{set listeners}.
6707A set listener listens for incoming operations of a specific operation
6708type and application id.
6709Once notified of an incoming set request, the client can accept the set
6710request (providing a local set for the operation) or reject it.
6711
6712@node Result Elements
6713@subsection Result Elements
6714
6715
6716
6717The SET service has three @emph{result modes} that determine how an
6718operation's result set is delivered to the client:
6719
6720@itemize @bullet
6721@item @strong{Full Result Set.} All elements of set resulting from the set
6722operation are returned to the client.
6723@item @strong{Added Elements.} Only elements that result from the
6724operation and are not already in the local peer's set are returned.
6725Note that for some operations (like set intersection) this result mode
6726will never return any elements.
6727This can be useful if only the remove peer is actually interested in
6728the result of the set operation.
6729@item @strong{Removed Elements.} Only elements that are in the local
6730peer's initial set but not in the operation's result set are returned.
6731Note that for some operations (like set union) this result mode will
6732never return any elements. This can be useful if only the remove peer is
6733actually interested in the result of the set operation.
6734@end itemize
6735
6736@cindex libgnunetset
6737@node libgnunetset
6738@subsection libgnunetset
6739
6740
6741
6742@menu
6743* Sets::
6744* Listeners::
6745* Operations::
6746* Supplying a Set::
6747* The Result Callback::
6748@end menu
6749
6750@node Sets
6751@subsubsection Sets
6752
6753
6754
6755New sets are created with @code{GNUNET_SET_create}. Both the local peer's
6756configuration (as each set has its own client connection) and the
6757operation type must be specified.
6758The set exists until either the client calls @code{GNUNET_SET_destroy} or
6759the client's connection to the service is disrupted.
6760In the latter case, the client is notified by the return value of
6761functions dealing with sets. This return value must always be checked.
6762
6763Elements are added and removed with @code{GNUNET_SET_add_element} and
6764@code{GNUNET_SET_remove_element}.
6765
6766@node Listeners
6767@subsubsection Listeners
6768
6769
6770
6771Listeners are created with @code{GNUNET_SET_listen}. Each time time a
6772remote peer suggests a set operation with an application id and operation
6773type matching a listener, the listener's callback is invoked.
6774The client then must synchronously call either @code{GNUNET_SET_accept}
6775or @code{GNUNET_SET_reject}. Note that the operation will not be started
6776until the client calls @code{GNUNET_SET_commit}
6777(see Section "Supplying a Set").
6778
6779@node Operations
6780@subsubsection Operations
6781
6782
6783
6784Operations to be initiated by the local peer are created with
6785@code{GNUNET_SET_prepare}. Note that the operation will not be started
6786until the client calls @code{GNUNET_SET_commit}
6787(see Section "Supplying a Set").
6788
6789@node Supplying a Set
6790@subsubsection Supplying a Set
6791
6792
6793
6794To create symmetry between the two ways of starting a set operation
6795(accepting and initiating it), the operation handles returned by
6796@code{GNUNET_SET_accept} and @code{GNUNET_SET_prepare} do not yet have a
6797set to operate on, thus they can not do any work yet.
6798
6799The client must call @code{GNUNET_SET_commit} to specify a set to use for
6800an operation. @code{GNUNET_SET_commit} may only be called once per set
6801operation.
6802
6803@node The Result Callback
6804@subsubsection The Result Callback
6805
6806
6807
6808Clients must specify both a result mode and a result callback with
6809@code{GNUNET_SET_accept} and @code{GNUNET_SET_prepare}. The result
6810callback with a status indicating either that an element was received, or
6811the operation failed or succeeded.
6812The interpretation of the received element depends on the result mode.
6813The callback needs to know which result mode it is used in, as the
6814arguments do not indicate if an element is part of the full result set,
6815or if it is in the difference between the original set and the final set.
6816
6817@node The SET Client-Service Protocol
6818@subsection The SET Client-Service Protocol
6819
6820
6821
6822@menu
6823* Creating Sets::
6824* Listeners2::
6825* Initiating Operations::
6826* Modifying Sets::
6827* Results and Operation Status::
6828* Iterating Sets::
6829@end menu
6830
6831@node Creating Sets
6832@subsubsection Creating Sets
6833
6834
6835
6836For each set of a client, there exists a client connection to the service.
6837Sets are created by sending the @code{GNUNET_SERVICE_SET_CREATE} message
6838over a new client connection. Multiple operations for one set are
6839multiplexed over one client connection, using a request id supplied by
6840the client.
6841
6842@node Listeners2
6843@subsubsection Listeners2
6844
6845
6846
6847Each listener also requires a separate client connection. By sending the
6848@code{GNUNET_SERVICE_SET_LISTEN} message, the client notifies the service
6849of the application id and operation type it is interested in. A client
6850rejects an incoming request by sending @code{GNUNET_SERVICE_SET_REJECT}
6851on the listener's client connection.
6852In contrast, when accepting an incoming request, a
6853@code{GNUNET_SERVICE_SET_ACCEPT} message must be sent over the@ set that
6854is supplied for the set operation.
6855
6856@node Initiating Operations
6857@subsubsection Initiating Operations
6858
6859
6860
6861Operations with remote peers are initiated by sending a
6862@code{GNUNET_SERVICE_SET_EVALUATE} message to the service. The@ client
6863connection that this message is sent by determines the set to use.
6864
6865@node Modifying Sets
6866@subsubsection Modifying Sets
6867
6868
6869
6870Sets are modified with the @code{GNUNET_SERVICE_SET_ADD} and
6871@code{GNUNET_SERVICE_SET_REMOVE} messages.
6872
6873
6874@c %@menu
6875@c %* Results and Operation Status::
6876@c %* Iterating Sets::
6877@c %@end menu
6878
6879@node Results and Operation Status
6880@subsubsection Results and Operation Status
6881
6882
6883The service notifies the client of result elements and success/failure of
6884a set operation with the @code{GNUNET_SERVICE_SET_RESULT} message.
6885
6886@node Iterating Sets
6887@subsubsection Iterating Sets
6888
6889
6890
6891All elements of a set can be requested by sending
6892@code{GNUNET_SERVICE_SET_ITER_REQUEST}. The server responds with
6893@code{GNUNET_SERVICE_SET_ITER_ELEMENT} and eventually terminates the
6894iteration with @code{GNUNET_SERVICE_SET_ITER_DONE}.
6895After each received element, the client
6896must send @code{GNUNET_SERVICE_SET_ITER_ACK}. Note that only one set
6897iteration may be active for a set at any given time.
6898
6899@node The SET Intersection Peer-to-Peer Protocol
6900@subsection The SET Intersection Peer-to-Peer Protocol
6901
6902
6903
6904The intersection protocol operates over CADET and starts with a
6905GNUNET_MESSAGE_TYPE_SET_P2P_OPERATION_REQUEST being sent by the peer
6906initiating the operation to the peer listening for inbound requests.
6907It includes the number of elements of the initiating peer, which is used
6908to decide which side will send a Bloom filter first.
6909
6910The listening peer checks if the operation type and application
6911identifier are acceptable for its current state.
6912If not, it responds with a GNUNET_MESSAGE_TYPE_SET_RESULT and a status of
6913GNUNET_SET_STATUS_FAILURE (and terminates the CADET channel).
6914
6915If the application accepts the request, the listener sends back a
6916@code{GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_ELEMENT_INFO} if it has
6917more elements in the set than the client.
6918Otherwise, it immediately starts with the Bloom filter exchange.
6919If the initiator receives a
6920@code{GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_ELEMENT_INFO} response,
6921it beings the Bloom filter exchange, unless the set size is indicated to
6922be zero, in which case the intersection is considered finished after
6923just the initial handshake.
6924
6925
6926@menu
6927* The Bloom filter exchange::
6928* Salt::
6929@end menu
6930
6931@node The Bloom filter exchange
6932@subsubsection The Bloom filter exchange
6933
6934
6935
6936In this phase, each peer transmits a Bloom filter over the remaining
6937keys of the local set to the other peer using a
6938@code{GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_BF} message. This
6939message additionally includes the number of elements left in the sender's
6940set, as well as the XOR over all of the keys in that set.
6941
6942The number of bits 'k' set per element in the Bloom filter is calculated
6943based on the relative size of the two sets.
6944Furthermore, the size of the Bloom filter is calculated based on 'k' and
6945the number of elements in the set to maximize the amount of data filtered
6946per byte transmitted on the wire (while avoiding an excessively high
6947number of iterations).
6948
6949The receiver of the message removes all elements from its local set that
6950do not pass the Bloom filter test.
6951It then checks if the set size of the sender and the XOR over the keys
6952match what is left of its own set. If they do, it sends a
6953@code{GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_DONE} back to indicate
6954that the latest set is the final result.
6955Otherwise, the receiver starts another Bloom filter exchange, except
6956this time as the sender.
6957
6958@node Salt
6959@subsubsection Salt
6960
6961
6962
6963Bloomfilter operations are probabilistic: With some non-zero probability
6964the test may incorrectly say an element is in the set, even though it is
6965not.
6966
6967To mitigate this problem, the intersection protocol iterates exchanging
6968Bloom filters using a different random 32-bit salt in each iteration (the
6969salt is also included in the message).
6970With different salts, set operations may fail for different elements.
6971Merging the results from the executions, the probability of failure drops
6972to zero.
6973
6974The iterations terminate once both peers have established that they have
6975sets of the same size, and where the XOR over all keys computes the same
6976512-bit value (leaving a failure probability of 2-511).
6977
6978@node The SET Union Peer-to-Peer Protocol
6979@subsection The SET Union Peer-to-Peer Protocol
6980
6981
6982
6983The SET union protocol is based on Eppstein's efficient set reconciliation
6984without prior context. You should read this paper first if you want to
6985understand the protocol.
6986
6987The union protocol operates over CADET and starts with a
6988GNUNET_MESSAGE_TYPE_SET_P2P_OPERATION_REQUEST being sent by the peer
6989initiating the operation to the peer listening for inbound requests.
6990It includes the number of elements of the initiating peer, which is
6991currently not used.
6992
6993The listening peer checks if the operation type and application
6994identifier are acceptable for its current state. If not, it responds with
6995a @code{GNUNET_MESSAGE_TYPE_SET_RESULT} and a status of
6996@code{GNUNET_SET_STATUS_FAILURE} (and terminates the CADET channel).
6997
6998If the application accepts the request, it sends back a strata estimator
6999using a message of type GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SE. The
7000initiator evaluates the strata estimator and initiates the exchange of
7001invertible Bloom filters, sending a GNUNET_MESSAGE_TYPE_SET_UNION_P2P_IBF.
7002
7003During the IBF exchange, if the receiver cannot invert the Bloom filter or
7004detects a cycle, it sends a larger IBF in response (up to a defined
7005maximum limit; if that limit is reached, the operation fails).
7006Elements decoded while processing the IBF are transmitted to the other
7007peer using GNUNET_MESSAGE_TYPE_SET_P2P_ELEMENTS, or requested from the
7008other peer using GNUNET_MESSAGE_TYPE_SET_P2P_ELEMENT_REQUESTS messages,
7009depending on the sign observed during decoding of the IBF.
7010Peers respond to a GNUNET_MESSAGE_TYPE_SET_P2P_ELEMENT_REQUESTS message
7011with the respective element in a GNUNET_MESSAGE_TYPE_SET_P2P_ELEMENTS
7012message. If the IBF fully decodes, the peer responds with a
7013GNUNET_MESSAGE_TYPE_SET_UNION_P2P_DONE message instead of another
7014GNUNET_MESSAGE_TYPE_SET_UNION_P2P_IBF.
7015
7016All Bloom filter operations use a salt to mingle keys before hashing them
7017into buckets, such that future iterations have a fresh chance of
7018succeeding if they failed due to collisions before.
7019
7020
7021
7022
7023
7024
7025
7026
7027@cindex SETI Subsystem
7028@node SETI Subsystem
7029@section SETI Subsystem
7030
7031The SET service implements efficient set intersection between two peers
7032over a CADET tunnel.
7033Elements of a set consist of an @emph{element type} and
7034arbitrary binary @emph{data}.
7035The size of an element's data is limited to around 62 KB.
7036
7037@menu
7038* Intersection Sets::
7039* Set Intersection Modifications::
7040* Set Intersection Operations::
7041* Intersection Result Elements::
7042* libgnunetseti::
7043* The SETI Client-Service Protocol::
7044* The SETI Intersection Peer-to-Peer Protocol::
7045@end menu
7046
7047@node Intersection Sets
7048@subsection Intersection Sets
7049
7050Sets created by a local client can be modified (by adding additional elements)
7051and reused for multiple operations. If elements are to be removed, a fresh
7052set must be created by the client.
7053
7054@node Set Intersection Modifications
7055@subsection Set Intersection Modifications
7056
7057Even when set operations are active, one can add elements
7058to a set.
7059However, these changes will only be visible to operations that have been
7060created after the changes have taken place. That is, every set operation
7061only sees a snapshot of the set from the time the operation was started.
7062This mechanism is @emph{not} implemented by copying the whole set, but by
7063attaching @emph{generation information} to each element and operation.
7064
7065@node Set Intersection Operations
7066@subsection Set Intersection Operations
7067
7068Set operations can be started in two ways: Either by accepting an
7069operation request from a remote peer, or by requesting a set operation
7070from a remote peer.
7071Set operations are uniquely identified by the involved @emph{peers}, an
7072@emph{application id} and the @emph{operation type}.
7073
7074The client is notified of incoming set operations by @emph{set listeners}.
7075A set listener listens for incoming operations of a specific operation
7076type and application id.
7077Once notified of an incoming set request, the client can accept the set
7078request (providing a local set for the operation) or reject it.
7079
7080@node Intersection Result Elements
7081@subsection Intersection Result Elements
7082
7083The SET service has two @emph{result modes} that determine how an
7084operation's result set is delivered to the client:
7085
7086@itemize @bullet
7087@item @strong{Return intersection.} All elements of set resulting from the set
7088intersection are returned to the client.
7089@item @strong{Removed Elements.} Only elements that are in the local
7090peer's initial set but not in the intersection are returned.
7091@end itemize
7092
7093@cindex libgnunetseti
7094@node libgnunetseti
7095@subsection libgnunetseti
7096
7097@menu
7098* Intersection Set API::
7099* Intersection Listeners::
7100* Intersection Operations::
7101* Supplying a Set for Intersection::
7102* The Intersection Result Callback::
7103@end menu
7104
7105@node Intersection Set API
7106@subsubsection Intersection Set API
7107
7108New sets are created with @code{GNUNET_SETI_create}. Only the local peer's
7109configuration (as each set has its own client connection) must be provided.
7110The set exists until either the client calls @code{GNUNET_SET_destroy} or
7111the client's connection to the service is disrupted.
7112In the latter case, the client is notified by the return value of
7113functions dealing with sets. This return value must always be checked.
7114
7115Elements are added with @code{GNUNET_SET_add_element}.
7116
7117@node Intersection Listeners
7118@subsubsection Intersection Listeners
7119
7120Listeners are created with @code{GNUNET_SET_listen}. Each time time a
7121remote peer suggests a set operation with an application id and operation
7122type matching a listener, the listener's callback is invoked.
7123The client then must synchronously call either @code{GNUNET_SET_accept}
7124or @code{GNUNET_SET_reject}. Note that the operation will not be started
7125until the client calls @code{GNUNET_SET_commit}
7126(see Section "Supplying a Set").
7127
7128@node Intersection Operations
7129@subsubsection Intersection Operations
7130
7131Operations to be initiated by the local peer are created with
7132@code{GNUNET_SET_prepare}. Note that the operation will not be started
7133until the client calls @code{GNUNET_SET_commit}
7134(see Section "Supplying a Set").
7135
7136@node Supplying a Set for Intersection
7137@subsubsection Supplying a Set for Intersection
7138
7139To create symmetry between the two ways of starting a set operation
7140(accepting and initiating it), the operation handles returned by
7141@code{GNUNET_SET_accept} and @code{GNUNET_SET_prepare} do not yet have a
7142set to operate on, thus they can not do any work yet.
7143
7144The client must call @code{GNUNET_SET_commit} to specify a set to use for
7145an operation. @code{GNUNET_SET_commit} may only be called once per set
7146operation.
7147
7148@node The Intersection Result Callback
7149@subsubsection The Intersection Result Callback
7150
7151Clients must specify both a result mode and a result callback with
7152@code{GNUNET_SET_accept} and @code{GNUNET_SET_prepare}. The result
7153callback with a status indicating either that an element was received, or
7154the operation failed or succeeded.
7155The interpretation of the received element depends on the result mode.
7156The callback needs to know which result mode it is used in, as the
7157arguments do not indicate if an element is part of the full result set,
7158or if it is in the difference between the original set and the final set.
7159
7160@node The SETI Client-Service Protocol
7161@subsection The SETI Client-Service Protocol
7162
7163@menu
7164* Creating Intersection Sets::
7165* Listeners for Intersection::
7166* Initiating Intersection Operations::
7167* Modifying Intersection Sets::
7168* Intersection Results and Operation Status::
7169@end menu
7170
7171@node Creating Intersection Sets
7172@subsubsection Creating Intersection Sets
7173
7174For each set of a client, there exists a client connection to the service.
7175Sets are created by sending the @code{GNUNET_SERVICE_SETI_CREATE} message
7176over a new client connection. Multiple operations for one set are
7177multiplexed over one client connection, using a request id supplied by
7178the client.
7179
7180@node Listeners for Intersection
7181@subsubsection Listeners for Intersection
7182
7183Each listener also requires a separate client connection. By sending the
7184@code{GNUNET_SERVICE_SETI_LISTEN} message, the client notifies the service
7185of the application id and operation type it is interested in. A client
7186rejects an incoming request by sending @code{GNUNET_SERVICE_SETI_REJECT}
7187on the listener's client connection.
7188In contrast, when accepting an incoming request, a
7189@code{GNUNET_SERVICE_SETI_ACCEPT} message must be sent over the@ set that
7190is supplied for the set operation.
7191
7192@node Initiating Intersection Operations
7193@subsubsection Initiating Intersection Operations
7194
7195Operations with remote peers are initiated by sending a
7196@code{GNUNET_SERVICE_SETI_EVALUATE} message to the service. The@ client
7197connection that this message is sent by determines the set to use.
7198
7199@node Modifying Intersection Sets
7200@subsubsection Modifying Intersection Sets
7201
7202Sets are modified with the @code{GNUNET_SERVICE_SETI_ADD} message.
7203
7204
7205@c %@menu
7206@c %* Results and Operation Status::
7207@c %* Iterating Sets::
7208@c %@end menu
7209
7210@node Intersection Results and Operation Status
7211@subsubsection Intersection Results and Operation Status
7212
7213The service notifies the client of result elements and success/failure of
7214a set operation with the @code{GNUNET_SERVICE_SETI_RESULT} message.
7215
7216@node The SETI Intersection Peer-to-Peer Protocol
7217@subsection The SETI Intersection Peer-to-Peer Protocol
7218
7219The intersection protocol operates over CADET and starts with a
7220GNUNET_MESSAGE_TYPE_SETI_P2P_OPERATION_REQUEST being sent by the peer
7221initiating the operation to the peer listening for inbound requests.
7222It includes the number of elements of the initiating peer, which is used
7223to decide which side will send a Bloom filter first.
7224
7225The listening peer checks if the operation type and application
7226identifier are acceptable for its current state.
7227If not, it responds with a GNUNET_MESSAGE_TYPE_SETI_RESULT and a status of
7228GNUNET_SETI_STATUS_FAILURE (and terminates the CADET channel).
7229
7230If the application accepts the request, the listener sends back a
7231@code{GNUNET_MESSAGE_TYPE_SETI_P2P_ELEMENT_INFO} if it has
7232more elements in the set than the client.
7233Otherwise, it immediately starts with the Bloom filter exchange.
7234If the initiator receives a
7235@code{GNUNET_MESSAGE_TYPE_SETI_P2P_ELEMENT_INFO} response,
7236it beings the Bloom filter exchange, unless the set size is indicated to
7237be zero, in which case the intersection is considered finished after
7238just the initial handshake.
7239
7240
7241@menu
7242* The Bloom filter exchange in SETI::
7243* Intersection Salt::
7244@end menu
7245
7246@node The Bloom filter exchange in SETI
7247@subsubsection The Bloom filter exchange in SETI
7248
7249In this phase, each peer transmits a Bloom filter over the remaining
7250keys of the local set to the other peer using a
7251@code{GNUNET_MESSAGE_TYPE_SETI_P2P_BF} message. This
7252message additionally includes the number of elements left in the sender's
7253set, as well as the XOR over all of the keys in that set.
7254
7255The number of bits 'k' set per element in the Bloom filter is calculated
7256based on the relative size of the two sets.
7257Furthermore, the size of the Bloom filter is calculated based on 'k' and
7258the number of elements in the set to maximize the amount of data filtered
7259per byte transmitted on the wire (while avoiding an excessively high
7260number of iterations).
7261
7262The receiver of the message removes all elements from its local set that
7263do not pass the Bloom filter test.
7264It then checks if the set size of the sender and the XOR over the keys
7265match what is left of its own set. If they do, it sends a
7266@code{GNUNET_MESSAGE_TYPE_SETI_P2P_DONE} back to indicate
7267that the latest set is the final result.
7268Otherwise, the receiver starts another Bloom filter exchange, except
7269this time as the sender.
7270
7271@node Intersection Salt
7272@subsubsection Intersection Salt
7273
7274Bloom filter operations are probabilistic: With some non-zero probability
7275the test may incorrectly say an element is in the set, even though it is
7276not.
7277
7278To mitigate this problem, the intersection protocol iterates exchanging
7279Bloom filters using a different random 32-bit salt in each iteration (the
7280salt is also included in the message).
7281With different salts, set operations may fail for different elements.
7282Merging the results from the executions, the probability of failure drops
7283to zero.
7284
7285The iterations terminate once both peers have established that they have
7286sets of the same size, and where the XOR over all keys computes the same
7287512-bit value (leaving a failure probability of 2-511).
7288
7289
7290@cindex SETU Subsystem
7291@node SETU Subsystem
7292@section SETU Subsystem
7293
7294The SETU service implements efficient set union operations between two peers
7295over a CADET tunnel. Elements of a set consist of an @emph{element type} and
7296arbitrary binary @emph{data}. The size of an element's data is limited to
7297around 62 KB.
7298
7299@menu
7300* Union Sets::
7301* Set Union Modifications::
7302* Set Union Operations::
7303* Union Result Elements::
7304* libgnunetsetu::
7305* The SETU Client-Service Protocol::
7306* The SETU Union Peer-to-Peer Protocol::
7307@end menu
7308
7309@node Union Sets
7310@subsection Union Sets
7311
7312Sets created by a local client can be modified (by adding additional elements)
7313and reused for multiple operations. If elements are to be removed, a fresh
7314set must be created by the client.
7315
7316@node Set Union Modifications
7317@subsection Set Union Modifications
7318
7319Even when set operations are active, one can add elements
7320to a set.
7321However, these changes will only be visible to operations that have been
7322created after the changes have taken place. That is, every set operation
7323only sees a snapshot of the set from the time the operation was started.
7324This mechanism is @emph{not} implemented by copying the whole set, but by
7325attaching @emph{generation information} to each element and operation.
7326
7327@node Set Union Operations
7328@subsection Set Union Operations
7329
7330Set operations can be started in two ways: Either by accepting an
7331operation request from a remote peer, or by requesting a set operation
7332from a remote peer.
7333Set operations are uniquely identified by the involved @emph{peers}, an
7334@emph{application id} and the @emph{operation type}.
7335
7336The client is notified of incoming set operations by @emph{set listeners}.
7337A set listener listens for incoming operations of a specific operation
7338type and application id.
7339Once notified of an incoming set request, the client can accept the set
7340request (providing a local set for the operation) or reject it.
7341
7342@node Union Result Elements
7343@subsection Union Result Elements
7344
7345The SET service has three @emph{result modes} that determine how an
7346operation's result set is delivered to the client:
7347
7348@itemize @bullet
7349@item @strong{Locally added Elements.} Elements that are in the union
7350but not already in the local peer's set are returned.
7351@item @strong{Remote added Elements.} Additionally, notify the client
7352if the remote peer lacked some elements and thus also return to the
7353local client those elements that we are sending to the remote peer to
7354be added to its union. Obtaining these elements requires setting
7355the @code{GNUNET_SETU_OPTION_SYMMETRIC} option.
7356@end itemize
7357
7358@cindex libgnunetsetu
7359@node libgnunetsetu
7360@subsection libgnunetsetu
7361
7362@menu
7363* Union Set API::
7364* Union Listeners::
7365* Union Operations::
7366* Supplying a Set for Union::
7367* The Union Result Callback::
7368@end menu
7369
7370@node Union Set API
7371@subsubsection Union Set API
7372
7373New sets are created with @code{GNUNET_SETU_create}. Only the local peer's
7374configuration (as each set has its own client connection) must be provided.
7375The set exists until either the client calls @code{GNUNET_SETU_destroy} or
7376the client's connection to the service is disrupted.
7377In the latter case, the client is notified by the return value of
7378functions dealing with sets. This return value must always be checked.
7379
7380Elements are added with @code{GNUNET_SETU_add_element}.
7381
7382@node Union Listeners
7383@subsubsection Union Listeners
7384
7385Listeners are created with @code{GNUNET_SETU_listen}. Each time time a
7386remote peer suggests a set operation with an application id and operation
7387type matching a listener, the listener's callback is invoked.
7388The client then must synchronously call either @code{GNUNET_SETU_accept}
7389or @code{GNUNET_SETU_reject}. Note that the operation will not be started
7390until the client calls @code{GNUNET_SETU_commit}
7391(see Section "Supplying a Set").
7392
7393@node Union Operations
7394@subsubsection Union Operations
7395
7396Operations to be initiated by the local peer are created with
7397@code{GNUNET_SETU_prepare}. Note that the operation will not be started
7398until the client calls @code{GNUNET_SETU_commit}
7399(see Section "Supplying a Set").
7400
7401@node Supplying a Set for Union
7402@subsubsection Supplying a Set for Union
7403
7404To create symmetry between the two ways of starting a set operation
7405(accepting and initiating it), the operation handles returned by
7406@code{GNUNET_SETU_accept} and @code{GNUNET_SETU_prepare} do not yet have a
7407set to operate on, thus they can not do any work yet.
7408
7409The client must call @code{GNUNET_SETU_commit} to specify a set to use for
7410an operation. @code{GNUNET_SETU_commit} may only be called once per set
7411operation.
7412
7413@node The Union Result Callback
7414@subsubsection The Union Result Callback
7415
7416Clients must specify both a result mode and a result callback with
7417@code{GNUNET_SETU_accept} and @code{GNUNET_SETU_prepare}. The result
7418callback with a status indicating either that an element was received,
7419transmitted to the other peer (if this information was requested), or
7420if the operation failed or ultimately succeeded.
7421
7422@node The SETU Client-Service Protocol
7423@subsection The SETU Client-Service Protocol
7424
7425@menu
7426* Creating Union Sets::
7427* Listeners for Union::
7428* Initiating Union Operations::
7429* Modifying Union Sets::
7430* Union Results and Operation Status::
7431@end menu
7432
7433@node Creating Union Sets
7434@subsubsection Creating Union Sets
7435
7436For each set of a client, there exists a client connection to the service.
7437Sets are created by sending the @code{GNUNET_SERVICE_SETU_CREATE} message
7438over a new client connection. Multiple operations for one set are
7439multiplexed over one client connection, using a request id supplied by
7440the client.
7441
7442@node Listeners for Union
7443@subsubsection Listeners for Union
7444
7445Each listener also requires a separate client connection. By sending the
7446@code{GNUNET_SERVICE_SETU_LISTEN} message, the client notifies the service
7447of the application id and operation type it is interested in. A client
7448rejects an incoming request by sending @code{GNUNET_SERVICE_SETU_REJECT}
7449on the listener's client connection.
7450In contrast, when accepting an incoming request, a
7451@code{GNUNET_SERVICE_SETU_ACCEPT} message must be sent over the@ set that
7452is supplied for the set operation.
7453
7454@node Initiating Union Operations
7455@subsubsection Initiating Union Operations
7456
7457
7458
7459Operations with remote peers are initiated by sending a
7460@code{GNUNET_SERVICE_SETU_EVALUATE} message to the service. The@ client
7461connection that this message is sent by determines the set to use.
7462
7463@node Modifying Union Sets
7464@subsubsection Modifying Union Sets
7465
7466Sets are modified with the @code{GNUNET_SERVICE_SETU_ADD} message.
7467
7468
7469@c %@menu
7470@c %* Results and Operation Status::
7471@c %* Iterating Sets::
7472@c %@end menu
7473
7474@node Union Results and Operation Status
7475@subsubsection Union Results and Operation Status
7476
7477The service notifies the client of result elements and success/failure of
7478a set operation with the @code{GNUNET_SERVICE_SETU_RESULT} message.
7479
7480
7481@node The SETU Union Peer-to-Peer Protocol
7482@subsection The SETU Union Peer-to-Peer Protocol
7483
7484
7485The SET union protocol is based on Eppstein's efficient set reconciliation
7486without prior context. You should read this paper first if you want to
7487understand the protocol.
7488
7489The union protocol operates over CADET and starts with a
7490GNUNET_MESSAGE_TYPE_SETU_P2P_OPERATION_REQUEST being sent by the peer
7491initiating the operation to the peer listening for inbound requests.
7492It includes the number of elements of the initiating peer, which is
7493currently not used.
7494
7495The listening peer checks if the operation type and application
7496identifier are acceptable for its current state. If not, it responds with
7497a @code{GNUNET_MESSAGE_TYPE_SETU_RESULT} and a status of
7498@code{GNUNET_SETU_STATUS_FAILURE} (and terminates the CADET channel).
7499
7500If the application accepts the request, it sends back a strata estimator
7501using a message of type GNUNET_MESSAGE_TYPE_SETU_P2P_SE. The
7502initiator evaluates the strata estimator and initiates the exchange of
7503invertible Bloom filters, sending a GNUNET_MESSAGE_TYPE_SETU_P2P_IBF.
7504
7505During the IBF exchange, if the receiver cannot invert the Bloom filter or
7506detects a cycle, it sends a larger IBF in response (up to a defined
7507maximum limit; if that limit is reached, the operation fails).
7508Elements decoded while processing the IBF are transmitted to the other
7509peer using GNUNET_MESSAGE_TYPE_SETU_P2P_ELEMENTS, or requested from the
7510other peer using GNUNET_MESSAGE_TYPE_SETU_P2P_ELEMENT_REQUESTS messages,
7511depending on the sign observed during decoding of the IBF.
7512Peers respond to a GNUNET_MESSAGE_TYPE_SETU_P2P_ELEMENT_REQUESTS message
7513with the respective element in a GNUNET_MESSAGE_TYPE_SETU_P2P_ELEMENTS
7514message. If the IBF fully decodes, the peer responds with a
7515GNUNET_MESSAGE_TYPE_SETU_P2P_DONE message instead of another
7516GNUNET_MESSAGE_TYPE_SETU_P2P_IBF.
7517
7518All Bloom filter operations use a salt to mingle keys before hashing them
7519into buckets, such that future iterations have a fresh chance of
7520succeeding if they failed due to collisions before.
7521
7522
7523
7524
7525
7526
7527@cindex STATISTICS Subsystem
7528@node STATISTICS Subsystem
7529@section STATISTICS Subsystem
7530
7531
7532
7533In GNUnet, the STATISTICS subsystem offers a central place for all
7534subsystems to publish unsigned 64-bit integer run-time statistics.
7535Keeping this information centrally means that there is a unified way for
7536the user to obtain data on all subsystems, and individual subsystems do
7537not have to always include a custom data export method for performance
7538metrics and other statistics. For example, the TRANSPORT system uses
7539STATISTICS to update information about the number of directly connected
7540peers and the bandwidth that has been consumed by the various plugins.
7541This information is valuable for diagnosing connectivity and performance
7542issues.
7543
7544Following the GNUnet service architecture, the STATISTICS subsystem is
7545divided into an API which is exposed through the header
7546@strong{gnunet_statistics_service.h} and the STATISTICS service
7547@strong{gnunet-service-statistics}. The @strong{gnunet-statistics}
7548command-line tool can be used to obtain (and change) information about
7549the values stored by the STATISTICS service. The STATISTICS service does
7550not communicate with other peers.
7551
7552Data is stored in the STATISTICS service in the form of tuples
7553@strong{(subsystem, name, value, persistence)}. The subsystem determines
7554to which other GNUnet's subsystem the data belongs. name is the name
7555through which value is associated. It uniquely identifies the record
7556from among other records belonging to the same subsystem.
7557In some parts of the code, the pair @strong{(subsystem, name)} is called
7558a @strong{statistic} as it identifies the values stored in the STATISTCS
7559service.The persistence flag determines if the record has to be preserved
7560across service restarts. A record is said to be persistent if this flag
7561is set for it; if not, the record is treated as a non-persistent record
7562and it is lost after service restart. Persistent records are written to
7563and read from the file @strong{statistics.data} before shutdown
7564and upon startup. The file is located in the HOME directory of the peer.
7565
7566An anomaly of the STATISTICS service is that it does not terminate
7567immediately upon receiving a shutdown signal if it has any clients
7568connected to it. It waits for all the clients that are not monitors to
7569close their connections before terminating itself.
7570This is to prevent the loss of data during peer shutdown --- delaying the
7571STATISTICS service shutdown helps other services to store important data
7572to STATISTICS during shutdown.
7573
7574@menu
7575* libgnunetstatistics::
7576* The STATISTICS Client-Service Protocol::
7577@end menu
7578
7579@cindex libgnunetstatistics
7580@node libgnunetstatistics
7581@subsection libgnunetstatistics
7582
7583
7584
7585@strong{libgnunetstatistics} is the library containing the API for the
7586STATISTICS subsystem. Any process requiring to use STATISTICS should use
7587this API by to open a connection to the STATISTICS service.
7588This is done by calling the function @code{GNUNET_STATISTICS_create()}.
7589This function takes the subsystem's name which is trying to use STATISTICS
7590and a configuration.
7591All values written to STATISTICS with this connection will be placed in
7592the section corresponding to the given subsystem's name.
7593The connection to STATISTICS can be destroyed with the function
7594@code{GNUNET_STATISTICS_destroy()}. This function allows for the
7595connection to be destroyed immediately or upon transferring all
7596pending write requests to the service.
7597
7598Note: STATISTICS subsystem can be disabled by setting @code{DISABLE = YES}
7599under the @code{[STATISTICS]} section in the configuration. With such a
7600configuration all calls to @code{GNUNET_STATISTICS_create()} return
7601@code{NULL} as the STATISTICS subsystem is unavailable and no other
7602functions from the API can be used.
7603
7604
7605@menu
7606* Statistics retrieval::
7607* Setting statistics and updating them::
7608* Watches::
7609@end menu
7610
7611@node Statistics retrieval
7612@subsubsection Statistics retrieval
7613
7614
7615
7616Once a connection to the statistics service is obtained, information
7617about any other system which uses statistics can be retrieved with the
7618function GNUNET_STATISTICS_get().
7619This function takes the connection handle, the name of the subsystem
7620whose information we are interested in (a @code{NULL} value will
7621retrieve information of all available subsystems using STATISTICS), the
7622name of the statistic we are interested in (a @code{NULL} value will
7623retrieve all available statistics), a continuation callback which is
7624called when all of requested information is retrieved, an iterator
7625callback which is called for each parameter in the retrieved information
7626and a closure for the aforementioned callbacks. The library then invokes
7627the iterator callback for each value matching the request.
7628
7629Call to @code{GNUNET_STATISTICS_get()} is asynchronous and can be
7630canceled with the function @code{GNUNET_STATISTICS_get_cancel()}.
7631This is helpful when retrieving statistics takes too long and especially
7632when we want to shutdown and cleanup everything.
7633
7634@node Setting statistics and updating them
7635@subsubsection Setting statistics and updating them
7636
7637
7638
7639So far we have seen how to retrieve statistics, here we will learn how we
7640can set statistics and update them so that other subsystems can retrieve
7641them.
7642
7643A new statistic can be set using the function
7644@code{GNUNET_STATISTICS_set()}.
7645This function takes the name of the statistic and its value and a flag to
7646make the statistic persistent.
7647The value of the statistic should be of the type @code{uint64_t}.
7648The function does not take the name of the subsystem; it is determined
7649from the previous @code{GNUNET_STATISTICS_create()} invocation. If
7650the given statistic is already present, its value is overwritten.
7651
7652An existing statistics can be updated, i.e its value can be increased or
7653decreased by an amount with the function
7654@code{GNUNET_STATISTICS_update()}.
7655The parameters to this function are similar to
7656@code{GNUNET_STATISTICS_set()}, except that it takes the amount to be
7657changed as a type @code{int64_t} instead of the value.
7658
7659The library will combine multiple set or update operations into one
7660message if the client performs requests at a rate that is faster than the
7661available IPC with the STATISTICS service. Thus, the client does not have
7662to worry about sending requests too quickly.
7663
7664@node Watches
7665@subsubsection Watches
7666
7667
7668
7669As interesting feature of STATISTICS lies in serving notifications
7670whenever a statistic of our interest is modified.
7671This is achieved by registering a watch through the function
7672@code{GNUNET_STATISTICS_watch()}.
7673The parameters of this function are similar to those of
7674@code{GNUNET_STATISTICS_get()}.
7675Changes to the respective statistic's value will then cause the given
7676iterator callback to be called.
7677Note: A watch can only be registered for a specific statistic. Hence
7678the subsystem name and the parameter name cannot be @code{NULL} in a
7679call to @code{GNUNET_STATISTICS_watch()}.
7680
7681A registered watch will keep notifying any value changes until
7682@code{GNUNET_STATISTICS_watch_cancel()} is called with the same
7683parameters that are used for registering the watch.
7684
7685@node The STATISTICS Client-Service Protocol
7686@subsection The STATISTICS Client-Service Protocol
7687
7688
7689
7690@menu
7691* Statistics retrieval2::
7692* Setting and updating statistics::
7693* Watching for updates::
7694@end menu
7695
7696@node Statistics retrieval2
7697@subsubsection Statistics retrieval2
7698
7699
7700
7701To retrieve statistics, the client transmits a message of type
7702@code{GNUNET_MESSAGE_TYPE_STATISTICS_GET} containing the given subsystem
7703name and statistic parameter to the STATISTICS service.
7704The service responds with a message of type
7705@code{GNUNET_MESSAGE_TYPE_STATISTICS_VALUE} for each of the statistics
7706parameters that match the client request for the client. The end of
7707information retrieved is signaled by the service by sending a message of
7708type @code{GNUNET_MESSAGE_TYPE_STATISTICS_END}.
7709
7710@node Setting and updating statistics
7711@subsubsection Setting and updating statistics
7712
7713
7714
7715The subsystem name, parameter name, its value and the persistence flag are
7716communicated to the service through the message
7717@code{GNUNET_MESSAGE_TYPE_STATISTICS_SET}.
7718
7719When the service receives a message of type
7720@code{GNUNET_MESSAGE_TYPE_STATISTICS_SET}, it retrieves the subsystem
7721name and checks for a statistic parameter with matching the name given in
7722the message.
7723If a statistic parameter is found, the value is overwritten by the new
7724value from the message; if not found then a new statistic parameter is
7725created with the given name and value.
7726
7727In addition to just setting an absolute value, it is possible to perform a
7728relative update by sending a message of type
7729@code{GNUNET_MESSAGE_TYPE_STATISTICS_SET} with an update flag
7730(@code{GNUNET_STATISTICS_SETFLAG_RELATIVE}) signifying that the value in
7731the message should be treated as an update value.
7732
7733@node Watching for updates
7734@subsubsection Watching for updates
7735
7736
7737
7738The function registers the watch at the service by sending a message of
7739type @code{GNUNET_MESSAGE_TYPE_STATISTICS_WATCH}. The service then sends
7740notifications through messages of type
7741@code{GNUNET_MESSAGE_TYPE_STATISTICS_WATCH_VALUE} whenever the statistic
7742parameter's value is changed.
7743
7744@cindex DHT
7745@cindex Distributed Hash Table
7746@node Distributed Hash Table (DHT)
7747@section Distributed Hash Table (DHT)
7748
7749
7750
7751GNUnet includes a generic distributed hash table that can be used by
7752developers building P2P applications in the framework.
7753This section documents high-level features and how developers are
7754expected to use the DHT.
7755We have a research paper detailing how the DHT works.
7756Also, Nate's thesis includes a detailed description and performance
7757analysis (in chapter 6).
7758
7759Key features of GNUnet's DHT include:
7760
7761@itemize @bullet
7762@item stores key-value pairs with values up to (approximately) 63k in size
7763@item works with many underlay network topologies (small-world, random
7764graph), underlay does not need to be a full mesh / clique
7765@item support for extended queries (more than just a simple 'key'),
7766filtering duplicate replies within the network (bloomfilter) and content
7767validation (for details, please read the subsection on the block library)
7768@item can (optionally) return paths taken by the PUT and GET operations
7769to the application
7770@item provides content replication to handle churn
7771@end itemize
7772
7773GNUnet's DHT is randomized and unreliable. Unreliable means that there is
7774no strict guarantee that a value stored in the DHT is always
7775found --- values are only found with high probability.
7776While this is somewhat true in all P2P DHTs, GNUnet developers should be
7777particularly wary of this fact (this will help you write secure,
7778fault-tolerant code). Thus, when writing any application using the DHT,
7779you should always consider the possibility that a value stored in the
7780DHT by you or some other peer might simply not be returned, or returned
7781with a significant delay.
7782Your application logic must be written to tolerate this (naturally, some
7783loss of performance or quality of service is expected in this case).
7784
7785@menu
7786* Block library and plugins::
7787* libgnunetdht::
7788* The DHT Client-Service Protocol::
7789* The DHT Peer-to-Peer Protocol::
7790@end menu
7791
7792@node Block library and plugins
7793@subsection Block library and plugins
7794
7795
7796
7797@menu
7798* What is a Block?::
7799* The API of libgnunetblock::
7800* Queries::
7801* Sample Code::
7802* Conclusion2::
7803@end menu
7804
7805@node What is a Block?
7806@subsubsection What is a Block?
7807
7808
7809
7810Blocks are small (< 63k) pieces of data stored under a key (struct
7811GNUNET_HashCode). Blocks have a type (enum GNUNET_BlockType) which defines
7812their data format. Blocks are used in GNUnet as units of static data
7813exchanged between peers and stored (or cached) locally.
7814Uses of blocks include file-sharing (the files are broken up into blocks),
7815the VPN (DNS information is stored in blocks) and the DHT (all
7816information in the DHT and meta-information for the maintenance of the
7817DHT are both stored using blocks).
7818The block subsystem provides a few common functions that must be
7819available for any type of block.
7820
7821@cindex libgnunetblock API
7822@node The API of libgnunetblock
7823@subsubsection The API of libgnunetblock
7824
7825
7826
7827The block library requires for each (family of) block type(s) a block
7828plugin (implementing @file{gnunet_block_plugin.h}) that provides basic
7829functions that are needed by the DHT (and possibly other subsystems) to
7830manage the block.
7831These block plugins are typically implemented within their respective
7832subsystems.
7833The main block library is then used to locate, load and query the
7834appropriate block plugin.
7835Which plugin is appropriate is determined by the block type (which is
7836just a 32-bit integer). Block plugins contain code that specifies which
7837block types are supported by a given plugin. The block library loads all
7838block plugins that are installed at the local peer and forwards the
7839application request to the respective plugin.
7840
7841The central functions of the block APIs (plugin and main library) are to
7842allow the mapping of blocks to their respective key (if possible) and the
7843ability to check that a block is well-formed and matches a given
7844request (again, if possible).
7845This way, GNUnet can avoid storing invalid blocks, storing blocks under
7846the wrong key and forwarding blocks in response to a query that they do
7847not answer.
7848
7849One key function of block plugins is that it allows GNUnet to detect
7850duplicate replies (via the Bloom filter). All plugins MUST support
7851detecting duplicate replies (by adding the current response to the
7852Bloom filter and rejecting it if it is encountered again).
7853If a plugin fails to do this, responses may loop in the network.
7854
7855@node Queries
7856@subsubsection Queries
7857
7858
7859The query format for any block in GNUnet consists of four main components.
7860First, the type of the desired block must be specified. Second, the query
7861must contain a hash code. The hash code is used for lookups in hash
7862tables and databases and must not be unique for the block (however, if
7863possible a unique hash should be used as this would be best for
7864performance).
7865Third, an optional Bloom filter can be specified to exclude known results;
7866replies that hash to the bits set in the Bloom filter are considered
7867invalid. False-positives can be eliminated by sending the same query
7868again with a different Bloom filter mutator value, which parametrizes
7869the hash function that is used.
7870Finally, an optional application-specific "eXtended query" (xquery) can
7871be specified to further constrain the results. It is entirely up to
7872the type-specific plugin to determine whether or not a given block
7873matches a query (type, hash, Bloom filter, and xquery).
7874Naturally, not all xquery's are valid and some types of blocks may not
7875support Bloom filters either, so the plugin also needs to check if the
7876query is valid in the first place.
7877
7878Depending on the results from the plugin, the DHT will then discard the
7879(invalid) query, forward the query, discard the (invalid) reply, cache the
7880(valid) reply, and/or forward the (valid and non-duplicate) reply.
7881
7882@node Sample Code
7883@subsubsection Sample Code
7884
7885
7886
7887The source code in @strong{plugin_block_test.c} is a good starting point
7888for new block plugins --- it does the minimal work by implementing a
7889plugin that performs no validation at all.
7890The respective @strong{Makefile.am} shows how to build and install a
7891block plugin.
7892
7893@node Conclusion2
7894@subsubsection Conclusion2
7895
7896
7897
7898In conclusion, GNUnet subsystems that want to use the DHT need to define a
7899block format and write a plugin to match queries and replies. For testing,
7900the @code{GNUNET_BLOCK_TYPE_TEST} block type can be used; it accepts
7901any query as valid and any reply as matching any query.
7902This type is also used for the DHT command line tools.
7903However, it should NOT be used for normal applications due to the lack
7904of error checking that results from this primitive implementation.
7905
7906@cindex libgnunetdht
7907@node libgnunetdht
7908@subsection libgnunetdht
7909
7910
7911
7912The DHT API itself is pretty simple and offers the usual GET and PUT
7913functions that work as expected. The specified block type refers to the
7914block library which allows the DHT to run application-specific logic for
7915data stored in the network.
7916
7917
7918@menu
7919* GET::
7920* PUT::
7921* MONITOR::
7922* DHT Routing Options::
7923@end menu
7924
7925@node GET
7926@subsubsection GET
7927
7928
7929
7930When using GET, the main consideration for developers (other than the
7931block library) should be that after issuing a GET, the DHT will
7932continuously cause (small amounts of) network traffic until the operation
7933is explicitly canceled.
7934So GET does not simply send out a single network request once; instead,
7935the DHT will continue to search for data. This is needed to achieve good
7936success rates and also handles the case where the respective PUT
7937operation happens after the GET operation was started.
7938Developers should not cancel an existing GET operation and then
7939explicitly re-start it to trigger a new round of network requests;
7940this is simply inefficient, especially as the internal automated version
7941can be more efficient, for example by filtering results in the network
7942that have already been returned.
7943
7944If an application that performs a GET request has a set of replies that it
7945already knows and would like to filter, it can call@
7946@code{GNUNET_DHT_get_filter_known_results} with an array of hashes over
7947the respective blocks to tell the DHT that these results are not
7948desired (any more).
7949This way, the DHT will filter the respective blocks using the block
7950library in the network, which may result in a significant reduction in
7951bandwidth consumption.
7952
7953@node PUT
7954@subsubsection PUT
7955
7956
7957
7958@c inconsistent use of ``must'' above it's written ``MUST''
7959In contrast to GET operations, developers @strong{must} manually re-run
7960PUT operations periodically (if they intend the content to continue to be
7961available). Content stored in the DHT expires or might be lost due to
7962churn.
7963Furthermore, GNUnet's DHT typically requires multiple rounds of PUT
7964operations before a key-value pair is consistently available to all
7965peers (the DHT randomizes paths and thus storage locations, and only
7966after multiple rounds of PUTs there will be a sufficient number of
7967replicas in large DHTs). An explicit PUT operation using the DHT API will
7968only cause network traffic once, so in order to ensure basic availability
7969and resistance to churn (and adversaries), PUTs must be repeated.
7970While the exact frequency depends on the application, a rule of thumb is
7971that there should be at least a dozen PUT operations within the content
7972lifetime. Content in the DHT typically expires after one day, so
7973DHT PUT operations should be repeated at least every 1-2 hours.
7974
7975@node MONITOR
7976@subsubsection MONITOR
7977
7978
7979
7980The DHT API also allows applications to monitor messages crossing the
7981local DHT service.
7982The types of messages used by the DHT are GET, PUT and RESULT messages.
7983Using the monitoring API, applications can choose to monitor these
7984requests, possibly limiting themselves to requests for a particular block
7985type.
7986
7987The monitoring API is not only useful for diagnostics, it can also be
7988used to trigger application operations based on PUT operations.
7989For example, an application may use PUTs to distribute work requests to
7990other peers.
7991The workers would then monitor for PUTs that give them work, instead of
7992looking for work using GET operations.
7993This can be beneficial, especially if the workers have no good way to
7994guess the keys under which work would be stored.
7995Naturally, additional protocols might be needed to ensure that the desired
7996number of workers will process the distributed workload.
7997
7998@node DHT Routing Options
7999@subsubsection DHT Routing Options
8000
8001
8002
8003There are two important options for GET and PUT requests:
8004
8005@table @asis
8006@item GNUNET_DHT_RO_DEMULITPLEX_EVERYWHERE This option means that all
8007peers should process the request, even if their peer ID is not closest to
8008the key. For a PUT request, this means that all peers that a request
8009traverses may make a copy of the data.
8010Similarly for a GET request, all peers will check their local database
8011for a result. Setting this option can thus significantly improve caching
8012and reduce bandwidth consumption --- at the expense of a larger DHT
8013database. If in doubt, we recommend that this option should be used.
8014@item GNUNET_DHT_RO_RECORD_ROUTE This option instructs the DHT to record
8015the path that a GET or a PUT request is taking through the overlay
8016network. The resulting paths are then returned to the application with
8017the respective result. This allows the receiver of a result to construct
8018a path to the originator of the data, which might then be used for
8019routing. Naturally, setting this option requires additional bandwidth
8020and disk space, so applications should only set this if the paths are
8021needed by the application logic.
8022@item GNUNET_DHT_RO_FIND_PEER This option is an internal option used by
8023the DHT's peer discovery mechanism and should not be used by applications.
8024@item GNUNET_DHT_RO_BART This option is currently not implemented. It may
8025in the future offer performance improvements for clique topologies.
8026@end table
8027
8028@node The DHT Client-Service Protocol
8029@subsection The DHT Client-Service Protocol
8030
8031
8032
8033@menu
8034* PUTting data into the DHT::
8035* GETting data from the DHT::
8036* Monitoring the DHT::
8037@end menu
8038
8039@node PUTting data into the DHT
8040@subsubsection PUTting data into the DHT
8041
8042
8043
8044To store (PUT) data into the DHT, the client sends a
8045@code{struct GNUNET_DHT_ClientPutMessage} to the service.
8046This message specifies the block type, routing options, the desired
8047replication level, the expiration time, key,
8048value and a 64-bit unique ID for the operation. The service responds with
8049a @code{struct GNUNET_DHT_ClientPutConfirmationMessage} with the same
805064-bit unique ID. Note that the service sends the confirmation as soon as
8051it has locally processed the PUT request. The PUT may still be
8052propagating through the network at this time.
8053
8054In the future, we may want to change this to provide (limited) feedback
8055to the client, for example if we detect that the PUT operation had no
8056effect because the same key-value pair was already stored in the DHT.
8057However, changing this would also require additional state and messages
8058in the P2P interaction.
8059
8060@node GETting data from the DHT
8061@subsubsection GETting data from the DHT
8062
8063
8064
8065To retrieve (GET) data from the DHT, the client sends a
8066@code{struct GNUNET_DHT_ClientGetMessage} to the service. The message
8067specifies routing options, a replication level (for replicating the GET,
8068not the content), the desired block type, the key, the (optional)
8069extended query and unique 64-bit request ID.
8070
8071Additionally, the client may send any number of
8072@code{struct GNUNET_DHT_ClientGetResultSeenMessage}s to notify the
8073service about results that the client is already aware of.
8074These messages consist of the key, the unique 64-bit ID of the request,
8075and an arbitrary number of hash codes over the blocks that the client is
8076already aware of. As messages are restricted to 64k, a client that
8077already knows more than about a thousand blocks may need to send
8078several of these messages. Naturally, the client should transmit these
8079messages as quickly as possible after the original GET request such that
8080the DHT can filter those results in the network early on. Naturally, as
8081these messages are sent after the original request, it is conceivable
8082that the DHT service may return blocks that match those already known
8083to the client anyway.
8084
8085In response to a GET request, the service will send @code{struct
8086GNUNET_DHT_ClientResultMessage}s to the client. These messages contain the
8087block type, expiration, key, unique ID of the request and of course the
8088value (a block). Depending on the options set for the respective
8089operations, the replies may also contain the path the GET and/or the PUT
8090took through the network.
8091
8092A client can stop receiving replies either by disconnecting or by sending
8093a @code{struct GNUNET_DHT_ClientGetStopMessage} which must contain the
8094key and the 64-bit unique ID of the original request. Using an
8095explicit "stop" message is more common as this allows a client to run
8096many concurrent GET operations over the same connection with the DHT
8097service --- and to stop them individually.
8098
8099@node Monitoring the DHT
8100@subsubsection Monitoring the DHT
8101
8102
8103
8104To begin monitoring, the client sends a
8105@code{struct GNUNET_DHT_MonitorStartStop} message to the DHT service.
8106In this message, flags can be set to enable (or disable) monitoring of
8107GET, PUT and RESULT messages that pass through a peer. The message can
8108also restrict monitoring to a particular block type or a particular key.
8109Once monitoring is enabled, the DHT service will notify the client about
8110any matching event using @code{struct GNUNET_DHT_MonitorGetMessage}s for
8111GET events, @code{struct GNUNET_DHT_MonitorPutMessage} for PUT events
8112and @code{struct GNUNET_DHT_MonitorGetRespMessage} for RESULTs. Each of
8113these messages contains all of the information about the event.
8114
8115@node The DHT Peer-to-Peer Protocol
8116@subsection The DHT Peer-to-Peer Protocol
8117
8118
8119
8120@menu
8121* Routing GETs or PUTs::
8122* PUTting data into the DHT2::
8123* GETting data from the DHT2::
8124@end menu
8125
8126@node Routing GETs or PUTs
8127@subsubsection Routing GETs or PUTs
8128
8129
8130
8131When routing GETs or PUTs, the DHT service selects a suitable subset of
8132neighbours for forwarding. The exact number of neighbours can be zero or
8133more and depends on the hop counter of the query (initially zero) in
8134relation to the (log of) the network size estimate, the desired
8135replication level and the peer's connectivity.
8136Depending on the hop counter and our network size estimate, the selection
8137of the peers maybe randomized or by proximity to the key.
8138Furthermore, requests include a set of peers that a request has already
8139traversed; those peers are also excluded from the selection.
8140
8141@node PUTting data into the DHT2
8142@subsubsection PUTting data into the DHT2
8143
8144
8145
8146To PUT data into the DHT, the service sends a @code{struct PeerPutMessage}
8147of type @code{GNUNET_MESSAGE_TYPE_DHT_P2P_PUT} to the respective
8148neighbour.
8149In addition to the usual information about the content (type, routing
8150options, desired replication level for the content, expiration time, key
8151and value), the message contains a fixed-size Bloom filter with
8152information about which peers (may) have already seen this request.
8153This Bloom filter is used to ensure that DHT messages never loop back to
8154a peer that has already processed the request.
8155Additionally, the message includes the current hop counter and, depending
8156on the routing options, the message may include the full path that the
8157message has taken so far.
8158The Bloom filter should already contain the identity of the previous hop;
8159however, the path should not include the identity of the previous hop and
8160the receiver should append the identity of the sender to the path, not
8161its own identity (this is done to reduce bandwidth).
8162
8163@node GETting data from the DHT2
8164@subsubsection GETting data from the DHT2
8165
8166
8167
8168A peer can search the DHT by sending @code{struct PeerGetMessage}s of type
8169@code{GNUNET_MESSAGE_TYPE_DHT_P2P_GET} to other peers. In addition to the
8170usual information about the request (type, routing options, desired
8171replication level for the request, the key and the extended query), a GET
8172request also contains a hop counter, a Bloom filter over the peers
8173that have processed the request already and depending on the routing
8174options the full path traversed by the GET.
8175Finally, a GET request includes a variable-size second Bloom filter and a
8176so-called Bloom filter mutator value which together indicate which
8177replies the sender has already seen. During the lookup, each block that
8178matches they block type, key and extended query is additionally subjected
8179to a test against this Bloom filter.
8180The block plugin is expected to take the hash of the block and combine it
8181with the mutator value and check if the result is not yet in the Bloom
8182filter. The originator of the query will from time to time modify the
8183mutator to (eventually) allow false-positives filtered by the Bloom filter
8184to be returned.
8185
8186Peers that receive a GET request perform a local lookup (depending on
8187their proximity to the key and the query options) and forward the request
8188to other peers.
8189They then remember the request (including the Bloom filter for blocking
8190duplicate results) and when they obtain a matching, non-filtered response
8191a @code{struct PeerResultMessage} of type
8192@code{GNUNET_MESSAGE_TYPE_DHT_P2P_RESULT} is forwarded to the previous
8193hop.
8194Whenever a result is forwarded, the block plugin is used to update the
8195Bloom filter accordingly, to ensure that the same result is never
8196forwarded more than once.
8197The DHT service may also cache forwarded results locally if the
8198"CACHE_RESULTS" option is set to "YES" in the configuration.
8199
8200@cindex GNS
8201@cindex GNU Name System
8202@node GNU Name System (GNS)
8203@section GNU Name System (GNS)
8204
8205
8206
8207The GNU Name System (GNS) is a decentralized database that enables users
8208to securely resolve names to values.
8209Names can be used to identify other users (for example, in social
8210networking), or network services (for example, VPN services running at a
8211peer in GNUnet, or purely IP-based services on the Internet).
8212Users interact with GNS by typing in a hostname that ends in a
8213top-level domain that is configured in the ``GNS'' section, matches
8214an identity of the user or ends in a Base32-encoded public key.
8215
8216Videos giving an overview of most of the GNS and the motivations behind
8217it is available here and here.
8218The remainder of this chapter targets developers that are familiar with
8219high level concepts of GNS as presented in these talks.
8220@c TODO: Add links to here and here and to these.
8221
8222GNS-aware applications should use the GNS resolver to obtain the
8223respective records that are stored under that name in GNS.
8224Each record consists of a type, value, expiration time and flags.
8225
8226The type specifies the format of the value. Types below 65536 correspond
8227to DNS record types, larger values are used for GNS-specific records.
8228Applications can define new GNS record types by reserving a number and
8229implementing a plugin (which mostly needs to convert the binary value
8230representation to a human-readable text format and vice-versa).
8231The expiration time specifies how long the record is to be valid.
8232The GNS API ensures that applications are only given non-expired values.
8233The flags are typically irrelevant for applications, as GNS uses them
8234internally to control visibility and validity of records.
8235
8236Records are stored along with a signature.
8237The signature is generated using the private key of the authoritative
8238zone. This allows any GNS resolver to verify the correctness of a
8239name-value mapping.
8240
8241Internally, GNS uses the NAMECACHE to cache information obtained from
8242other users, the NAMESTORE to store information specific to the local
8243users, and the DHT to exchange data between users.
8244A plugin API is used to enable applications to define new GNS
8245record types.
8246
8247@menu
8248* libgnunetgns::
8249* libgnunetgnsrecord::
8250* GNS plugins::
8251* The GNS Client-Service Protocol::
8252* Hijacking the DNS-Traffic using gnunet-service-dns::
8253@c * Serving DNS lookups via GNS on W32::
8254* Importing DNS Zones into GNS::
8255* Registering names using the FCFS daemon::
8256@end menu
8257
8258@node libgnunetgns
8259@subsection libgnunetgns
8260
8261
8262
8263The GNS API itself is extremely simple. Clients first connect to the
8264GNS service using @code{GNUNET_GNS_connect}.
8265They can then perform lookups using @code{GNUNET_GNS_lookup} or cancel
8266pending lookups using @code{GNUNET_GNS_lookup_cancel}.
8267Once finished, clients disconnect using @code{GNUNET_GNS_disconnect}.
8268
8269@menu
8270* Looking up records::
8271* Accessing the records::
8272* Creating records::
8273* Future work::
8274@end menu
8275
8276@node Looking up records
8277@subsubsection Looking up records
8278
8279
8280
8281@code{GNUNET_GNS_lookup} takes a number of arguments:
8282
8283@table @asis
8284@item handle This is simply the GNS connection handle from
8285@code{GNUNET_GNS_connect}.
8286@item name The client needs to specify the name to
8287be resolved. This can be any valid DNS or GNS hostname.
8288@item zone The client
8289needs to specify the public key of the GNS zone against which the
8290resolution should be done.
8291Note that a key must be provided, the client should
8292look up plausible values using its configuration,
8293the identity service and by attempting to interpret the
8294TLD as a base32-encoded public key.
8295@item type This is the desired GNS or DNS record type
8296to look for. While all records for the given name will be returned, this
8297can be important if the client wants to resolve record types that
8298themselves delegate resolution, such as CNAME, PKEY or GNS2DNS.
8299Resolving a record of any of these types will only work if the respective
8300record type is specified in the request, as the GNS resolver will
8301otherwise follow the delegation and return the records from the
8302respective destination, instead of the delegating record.
8303@item only_cached This argument should typically be set to
8304@code{GNUNET_NO}. Setting it to @code{GNUNET_YES} disables resolution via
8305the overlay network.
8306@item shorten_zone_key If GNS encounters new names during resolution,
8307their respective zones can automatically be learned and added to the
8308"shorten zone". If this is desired, clients must pass the private key of
8309the shorten zone. If NULL is passed, shortening is disabled.
8310@item proc This argument identifies
8311the function to call with the result. It is given proc_cls, the number of
8312records found (possibly zero) and the array of the records as arguments.
8313proc will only be called once. After proc,> has been called, the lookup
8314must no longer be canceled.
8315@item proc_cls The closure for proc.
8316@end table
8317
8318@node Accessing the records
8319@subsubsection Accessing the records
8320
8321
8322
8323The @code{libgnunetgnsrecord} library provides an API to manipulate the
8324GNS record array that is given to proc. In particular, it offers
8325functions such as converting record values to human-readable
8326strings (and back). However, most @code{libgnunetgnsrecord} functions are
8327not interesting to GNS client applications.
8328
8329For DNS records, the @code{libgnunetdnsparser} library provides
8330functions for parsing (and serializing) common types of DNS records.
8331
8332@node Creating records
8333@subsubsection Creating records
8334
8335
8336
8337Creating GNS records is typically done by building the respective record
8338information (possibly with the help of @code{libgnunetgnsrecord} and
8339@code{libgnunetdnsparser}) and then using the @code{libgnunetnamestore} to
8340publish the information. The GNS API is not involved in this
8341operation.
8342
8343@node Future work
8344@subsubsection Future work
8345
8346
8347
8348In the future, we want to expand @code{libgnunetgns} to allow
8349applications to observe shortening operations performed during GNS
8350resolution, for example so that users can receive visual feedback when
8351this happens.
8352
8353@node libgnunetgnsrecord
8354@subsection libgnunetgnsrecord
8355
8356
8357
8358The @code{libgnunetgnsrecord} library is used to manipulate GNS
8359records (in plaintext or in their encrypted format).
8360Applications mostly interact with @code{libgnunetgnsrecord} by using the
8361functions to convert GNS record values to strings or vice-versa, or to
8362lookup a GNS record type number by name (or vice-versa).
8363The library also provides various other functions that are mostly
8364used internally within GNS, such as converting keys to names, checking for
8365expiration, encrypting GNS records to GNS blocks, verifying GNS block
8366signatures and decrypting GNS records from GNS blocks.
8367
8368We will now discuss the four commonly used functions of the API.@
8369@code{libgnunetgnsrecord} does not perform these operations itself,
8370but instead uses plugins to perform the operation.
8371GNUnet includes plugins to support common DNS record types as well as
8372standard GNS record types.
8373
8374@menu
8375* Value handling::
8376* Type handling::
8377@end menu
8378
8379@node Value handling
8380@subsubsection Value handling
8381
8382
8383
8384@code{GNUNET_GNSRECORD_value_to_string} can be used to convert
8385the (binary) representation of a GNS record value to a human readable,
83860-terminated UTF-8 string.
8387NULL is returned if the specified record type is not supported by any
8388available plugin.
8389
8390@code{GNUNET_GNSRECORD_string_to_value} can be used to try to convert a
8391human readable string to the respective (binary) representation of
8392a GNS record value.
8393
8394@node Type handling
8395@subsubsection Type handling
8396
8397
8398
8399@code{GNUNET_GNSRECORD_typename_to_number} can be used to obtain the
8400numeric value associated with a given typename. For example, given the
8401typename "A" (for DNS A reocrds), the function will return the number 1.
8402A list of common DNS record types is
8403@uref{http://en.wikipedia.org/wiki/List_of_DNS_record_types, here}.
8404Note that not all DNS record types are supported by GNUnet GNSRECORD
8405plugins at this time.
8406
8407@code{GNUNET_GNSRECORD_number_to_typename} can be used to obtain the
8408typename associated with a given numeric value.
8409For example, given the type number 1, the function will return the
8410typename "A".
8411
8412@node GNS plugins
8413@subsection GNS plugins
8414
8415
8416
8417Adding a new GNS record type typically involves writing (or extending) a
8418GNSRECORD plugin. The plugin needs to implement the
8419@code{gnunet_gnsrecord_plugin.h} API which provides basic functions that
8420are needed by GNSRECORD to convert typenames and values of the respective
8421record type to strings (and back).
8422These gnsrecord plugins are typically implemented within their respective
8423subsystems.
8424Examples for such plugins can be found in the GNSRECORD, GNS and
8425CONVERSATION subsystems.
8426
8427The @code{libgnunetgnsrecord} library is then used to locate, load and
8428query the appropriate gnsrecord plugin.
8429Which plugin is appropriate is determined by the record type (which is
8430just a 32-bit integer). The @code{libgnunetgnsrecord} library loads all
8431block plugins that are installed at the local peer and forwards the
8432application request to the plugins. If the record type is not
8433supported by the plugin, it should simply return an error code.
8434
8435The central functions of the block APIs (plugin and main library) are the
8436same four functions for converting between values and strings, and
8437typenames and numbers documented in the previous subsection.
8438
8439@node The GNS Client-Service Protocol
8440@subsection The GNS Client-Service Protocol
8441
8442
8443The GNS client-service protocol consists of two simple messages, the
8444@code{LOOKUP} message and the @code{LOOKUP_RESULT}. Each @code{LOOKUP}
8445message contains a unique 32-bit identifier, which will be included in the
8446corresponding response. Thus, clients can send many lookup requests in
8447parallel and receive responses out-of-order.
8448A @code{LOOKUP} request also includes the public key of the GNS zone,
8449the desired record type and fields specifying whether shortening is
8450enabled or networking is disabled. Finally, the @code{LOOKUP} message
8451includes the name to be resolved.
8452
8453The response includes the number of records and the records themselves
8454in the format created by @code{GNUNET_GNSRECORD_records_serialize}.
8455They can thus be deserialized using
8456@code{GNUNET_GNSRECORD_records_deserialize}.
8457
8458@node Hijacking the DNS-Traffic using gnunet-service-dns
8459@subsection Hijacking the DNS-Traffic using gnunet-service-dns
8460
8461
8462
8463This section documents how the gnunet-service-dns (and the
8464gnunet-helper-dns) intercepts DNS queries from the local system.
8465This is merely one method for how we can obtain GNS queries.
8466It is also possible to change @code{resolv.conf} to point to a machine
8467running @code{gnunet-dns2gns} or to modify libc's name system switch
8468(NSS) configuration to include a GNS resolution plugin.
8469The method described in this chapter is more of a last-ditch catch-all
8470approach.
8471
8472@code{gnunet-service-dns} enables intercepting DNS traffic using policy
8473based routing.
8474We MARK every outgoing DNS-packet if it was not sent by our application.
8475Using a second routing table in the Linux kernel these marked packets are
8476then routed through our virtual network interface and can thus be
8477captured unchanged.
8478
8479Our application then reads the query and decides how to handle it.
8480If the query can be addressed via GNS, it is passed to
8481@code{gnunet-service-gns} and resolved internally using GNS.
8482In the future, a reverse query for an address of the configured virtual
8483network could be answered with records kept about previous forward
8484queries.
8485Queries that are not hijacked by some application using the DNS service
8486will be sent to the original recipient.
8487The answer to the query will always be sent back through the virtual
8488interface with the original nameserver as source address.
8489
8490
8491@menu
8492* Network Setup Details::
8493@end menu
8494
8495@node Network Setup Details
8496@subsubsection Network Setup Details
8497
8498
8499
8500The DNS interceptor adds the following rules to the Linux kernel:
8501@example
8502iptables -t mangle -I OUTPUT 1 -p udp --sport $LOCALPORT --dport 53 \
8503-j ACCEPT iptables -t mangle -I OUTPUT 2 -p udp --dport 53 -j MARK \
8504--set-mark 3 ip rule add fwmark 3 table2 ip route add default via \
8505$VIRTUALDNS table2
8506@end example
8507
8508@c FIXME: Rewrite to reflect display which is no longer content by line
8509@c FIXME: due to the < 74 characters limit.
8510Line 1 makes sure that all packets coming from a port our application
8511opened beforehand (@code{$LOCALPORT}) will be routed normally.
8512Line 2 marks every other packet to a DNS-Server with mark 3 (chosen
8513arbitrarily). The third line adds a routing policy based on this mark
85143 via the routing table.
8515
8516@c @node Serving DNS lookups via GNS on W32
8517@c @subsection Serving DNS lookups via GNS on W32
8518
8519
8520
8521@c This section documents how the libw32nsp (and
8522@c gnunet-gns-helper-service-w32) do DNS resolutions of DNS queries on the
8523@c local system. This only applies to GNUnet running on W32.
8524
8525@c W32 has a concept of "Namespaces" and "Namespace providers".
8526@c These are used to present various name systems to applications in a
8527@c generic way.
8528@c Namespaces include DNS, mDNS, NLA and others. For each namespace any
8529@c number of providers could be registered, and they are queried in an order
8530@c of priority (which is adjustable).
8531
8532@c Applications can resolve names by using WSALookupService*() family of
8533@c functions.
8534
8535@c However, these are WSA-only facilities. Common BSD socket functions for
8536@c namespace resolutions are gethostbyname and getaddrinfo (among others).
8537@c These functions are implemented internally (by default - by mswsock,
8538@c which also implements the default DNS provider) as wrappers around
8539@c WSALookupService*() functions (see "Sample Code for a Service Provider"
8540@c on MSDN).
8541
8542@c On W32 GNUnet builds a libw32nsp - a namespace provider, which can then be
8543@c installed into the system by using w32nsp-install (and uninstalled by
8544@c w32nsp-uninstall), as described in "Installation Handbook".
8545
8546@c libw32nsp is very simple and has almost no dependencies. As a response to
8547@c NSPLookupServiceBegin(), it only checks that the provider GUID passed to
8548@c it by the caller matches GNUnet DNS Provider GUID,
8549@c then connects to
8550@c gnunet-gns-helper-service-w32 at 127.0.0.1:5353 (hardcoded) and sends the
8551@c name resolution request there, returning the connected socket to the
8552@c caller.
8553
8554@c When the caller invokes NSPLookupServiceNext(), libw32nsp reads a
8555@c completely formed reply from that socket, unmarshalls it, then gives
8556@c it back to the caller.
8557
8558@c At the moment gnunet-gns-helper-service-w32 is implemented to ever give
8559@c only one reply, and subsequent calls to NSPLookupServiceNext() will fail
8560@c with WSA_NODATA (first call to NSPLookupServiceNext() might also fail if
8561@c GNS failed to find the name, or there was an error connecting to it).
8562
8563@c gnunet-gns-helper-service-w32 does most of the processing:
8564
8565@c @itemize @bullet
8566@c @item Maintains a connection to GNS.
8567@c @item Reads GNS config and loads appropriate keys.
8568@c @item Checks service GUID and decides on the type of record to look up,
8569@c refusing to make a lookup outright when unsupported service GUID is
8570@c passed.
8571@c @item Launches the lookup
8572@c @end itemize
8573
8574@c When lookup result arrives, gnunet-gns-helper-service-w32 forms a complete
8575@c reply (including filling a WSAQUERYSETW structure and, possibly, a binary
8576@c blob with a hostent structure for gethostbyname() client), marshalls it,
8577@c and sends it back to libw32nsp. If no records were found, it sends an
8578@c empty header.
8579
8580@c This works for most normal applications that use gethostbyname() or
8581@c getaddrinfo() to resolve names, but fails to do anything with
8582@c applications that use alternative means of resolving names (such as
8583@c sending queries to a DNS server directly by themselves).
8584@c This includes some of well known utilities, like "ping" and "nslookup".
8585
8586@node Importing DNS Zones into GNS
8587@subsection Importing DNS Zones into GNS
8588
8589This section discusses the challenges and problems faced when writing the
8590Ascension tool. It also takes a look at possible improvements in the
8591future.
8592
8593Consider the following diagram that shows the workflow of Ascension:
8594
8595@image{images/ascension_ssd,6in,,Ascensions workflow}
8596
8597Further the interaction between components of GNUnet are shown in the diagram
8598below:
8599@center @image{images/ascension_interaction,,6in,Ascensions workflow}
8600
8601@menu
8602* Conversions between DNS and GNS::
8603* DNS Zone Size::
8604* Performance::
8605@end menu
8606
8607@cindex DNS Conversion
8608@node Conversions between DNS and GNS
8609@subsubsection Conversions between DNS and GNS
8610
8611The differences between the two name systems lies in the details and is not
8612always transparent. For instance an SRV record is converted to a BOX record
8613which is unique to GNS.
8614
8615This is done by converting to a BOX record from an existing SRV record:
8616
8617@example
8618# SRV
8619# _service._proto.name. TTL class SRV priority weight port target
8620_sip._tcp.example.com. 14000 IN SRV 0 0 5060 www.example.com.
8621# BOX
8622# TTL BOX flags port protocol recordtype priority weight port target
862314000 BOX n 5060 6 33 0 0 5060 www.example.com
8624@end example
8625
8626Other records that need to undergo such transformation is the MX record type,
8627as well as the SOA record type.
8628
8629Transformation of a SOA record into GNS works as described in the
8630following example. Very important to note are the rname and mname keys.
8631
8632@example
8633# BIND syntax for a clean SOA record
8634@ IN SOA master.example.com. hostmaster.example.com. (
8635 2017030300 ; serial
8636 3600 ; refresh
8637 1800 ; retry
8638 604800 ; expire
8639 600 ) ; ttl
8640# Recordline for adding the record
8641$ gnunet-namestore -z example.com -a -n @ -t SOA -V \
8642 rname=master.example.com mname=hostmaster.example.com \
8643 2017030300,3600,1800,604800,600 -e 7200s
8644@end example
8645
8646The transformation of MX records is done in a simple way.
8647@example
8648# mail.example.com. 3600 IN MX 10 mail.example.com.
8649$ gnunet-namestore -z example.com -n mail -R 3600 MX n 10,mail
8650@end example
8651
8652Finally, one of the biggest struggling points were the NS records that are
8653found in top level domain zones. The intended behaviour for those is to add
8654GNS2DNS records for those so that gnunet-gns can resolve records for those
8655domains on its own. Those require the values from DNS GLUE records, provided
8656they are within the same zone.
8657
8658The following two examples show one record with a GLUE record and the other one
8659does not have a GLUE record. This takes place in the 'com' TLD.
8660
8661@example
8662# ns1.example.com 86400 IN A 127.0.0.1
8663# example.com 86400 IN NS ns1.example.com.
8664$ gnunet-namestore -z com -n example -R 86400 GNS2DNS n \
8665 example.com@@127.0.0.1
8666
8667# example.com 86400 IN NS ns1.example.org.
8668$ gnunet-namestore -z com -n example -R 86400 GNS2DNS n \
8669 example.com@@ns1.example.org
8670@end example
8671
8672As you can see, one of the GNS2DNS records has an IP address listed and the
8673other one a DNS name. For the first one there is a GLUE record to do the
8674translation directly and the second one will issue another DNS query to figure
8675out the IP of ns1.example.org.
8676
8677A solution was found by creating a hierarchical zone structure in GNS and linking
8678the zones using PKEY records to one another. This allows the resolution of the
8679name servers to work within GNS while not taking control over unwanted zones.
8680
8681Currently the following record types are supported:
8682@itemize @bullet
8683@item A
8684@item AAAA
8685@item CNAME
8686@item MX
8687@item NS
8688@item SRV
8689@item TXT
8690@end itemize
8691
8692This is not due to technical limitations but rather a practical ones. The
8693problem occurs with DNSSEC enabled DNS zones. As records within those zones are
8694signed periodically, and every new signature is an update to the zone, there are
8695many revisions of zones. This results in a problem with bigger zones as there
8696are lots of records that have been signed again but no major changes. Also
8697trying to add records that are unknown that require a different format take time
8698as they cause a CLI call of the namestore. Furthermore certain record types
8699need transformation into a GNS compatible format which, depending on the record
8700type, takes more time.
8701
8702Further a blacklist was added to drop for instance DNSSEC related records. Also
8703if a record type is neither in the white list nor the blacklist it is considered
8704as a loss of data and a message is shown to the user. This helps with
8705transparency and also with contributing, as the not supported record types can
8706then be added accordingly.
8707
8708@node DNS Zone Size
8709@subsubsection DNS Zone Size
8710Another very big problem exists with very large zones. When migrating a small
8711zone the delay between adding of records and their expiry is negligible. However
8712when working with big zones that easily have more than a few million records
8713this delay becomes a problem.
8714
8715Records will start to expire well before the zone has finished migrating. This
8716is usually not a problem but can cause a high CPU load when a peer is restarted
8717and the records have expired.
8718
8719A good solution has not been found yet. One of the idea that floated around was
8720that the records should be added with the s (shadow) flag to keep the records
8721resolvable even if they expired. However this would introduce the problem of how
8722to detect if a record has been removed from the zone and would require deletion
8723of said record(s).
8724
8725Another problem that still persists is how to refresh records. Expired records
8726are still displayed when calling gnunet-namestore but do not resolve with
8727gnunet-gns. Zonemaster will sign the expired records again and make sure that
8728the records are still valid. With a recent change this was fixed as gnunet-gns
8729to improve the suffix lookup which allows for a fast lookup even with thousands
8730of local egos.
8731
8732Currently the pace of adding records in general is around 10 records per second.
8733Crypto is the upper limit for adding of records. The performance of your machine
8734can be tested with the perf_crypto_* tools. There is still a big discrepancy
8735between the pace of Ascension and the theoretical limit.
8736
8737A performance metric for measuring improvements has not yet been implemented in
8738Ascension.
8739
8740@node Performance
8741@subsubsection Performance
8742The performance when migrating a zone using the Ascension tool is limited by a
8743handful of factors. First of all ascension is written in Python3 and calls the
8744CLI tools of GNUnet. This is comparable to a fork and exec call which costs a
8745few CPU cycles. Furthermore all the records that are added to the same
8746label are signed using the zones private key. This signing operation is very
8747resource heavy and was optimized during development by adding the '-R'
8748(Recordline) option to gnunet-namestore which allows to specify multiple records
8749using the CLI tool. Assuming that in a TLD zone every domain has at least two
8750name servers this halves the amount of signatures needed.
8751
8752Another improvement that could be made is with the addition of multiple threads
8753or using asynchronous subprocesses when opening the GNUnet CLI tools. This could
8754be implemented by simply creating more workers in the program but performance
8755improvements were not tested.
8756
8757Ascension was tested using different hardware and database backends. Performance
8758differences between SQLite and postgresql are marginal and almost non existent.
8759What did make a huge impact on record adding performance was the storage medium.
8760On a traditional mechanical hard drive adding of records were slow compared to a
8761solid state disk.
8762
8763In conclusion there are many bottlenecks still around in the program, namely the
8764single threaded implementation and inefficient, sequential calls of
8765gnunet-namestore. In the future a solution that uses the C API would be cleaner
8766and better.
8767
8768@node Registering names using the FCFS daemon
8769@subsection Registering names using the FCFS daemon
8770
8771This section describes FCFSD, a daemon used to associate names with PKEY
8772records following a ``First Come, First Served'' policy. This policy means
8773that a certain name can not be registered again if someone registered it
8774already.
8775
8776The daemon can be started by using @code{gnunet-namestore-fcfsd}, which will
8777start a simple HTTP server on localhost, using a port specified by the
8778@code{HTTPORT} value in its configuration.
8779
8780Communication is performed by sending GET or POST requests to specific paths
8781(``endpoints''), as described in the following sections.
8782
8783The daemon will always respond with data structured using the JSON format.
8784The fields to be expected will be listed for each endpoint.
8785
8786The only exceptions are for the ``root'' endpoint (i.e. @code{/}) which will
8787return a HTML document, and two other HTML documents which will be served when
8788certain errors are encountered, like when requesting an unknown endpoint.
8789
8790@menu
8791* Obtaining information from the daemon::
8792* Submitting data to the daemon::
8793* Customizing the HTML output::
8794@end menu
8795
8796@cindex FCFSD GET requests
8797@node Obtaining information from the daemon
8798@subsubsection Obtaining information from the daemon
8799
8800To query the daemon, a GET request must be sent to these endpoints, placing
8801parameters in the address as per the HTTP specification, like so:
8802
8803@example
8804GET /endpoint?param1=value&param2=value
8805@end example
8806
8807Each endpoint will be described using its name (@code{/endpoint} in the
8808example above), followed by the name of each parameter (like @code{param1} and
8809@code{param2}.)
8810
8811@deffn Endpoint /search name
8812This endpoint is used to query about the state of @var{name}, that is, whether
8813it is available for registration or not.
8814
8815The response JSON will contain two fields:
8816
8817@itemize @bullet
8818@item error
8819@item free
8820@end itemize
8821
8822@code{error} can be either the string @code{"true"} or the string
8823@code{"false"}: when @code{"true"}, it means there was an error within the
8824daemon and the name could not be searched at all.
8825
8826@code{free} can be either the string @code{"true"} or the string
8827@code{"false"}: when @code{"true"}, the requested name can be registered.
8828@end deffn
8829
8830@cindex FCFSD POST requests
8831@node Submitting data to the daemon
8832@subsubsection Submitting data to the daemon
8833
8834To send data to the daemon, a POST request must be sent to these endpoints,
8835placing the data to submit in the body of the request, structured using the
8836JSON format, like so:
8837
8838@example
8839POST /endpoint
8840Content-Type: application/json
8841...
8842
8843@{"param1": value1, "param2": value2, ...@}
8844@end example
8845
8846Each endpoint will be described using its name (@code{/endpoint} in the
8847example above), followed by the name of each JSON field (like @code{param1}
8848and @code{param2}.)
8849
8850@deffn Endpoint /register name key
8851This endpoint is used to register a new association between @var{name} and
8852@var{key}.
8853
8854For this operation to succeed, both @var{NAME} and @var{KEY} @strong{must not}
8855be registered already.
8856
8857The response JSON will contain two fields:
8858
8859@itemize @bullet
8860@item error
8861@item message
8862@end itemize
8863
8864@code{error} can be either the string @code{"true"} or the string
8865@code{"false"}: when @code{"true"}, it means the name could not be registered.
8866Clients can get the reason of the failure from the HTTP response code or from
8867the @code{message} field.
8868
8869@code{message} is a string which can be used by clients to let users know the
8870result of the operation. It might be localized to the daemon operator's
8871locale.
8872@end deffn
8873
8874@node Customizing the HTML output
8875@subsubsection Customizing the HTML output
8876
8877In some situations, the daemon will serve HTML documents instead of JSON
8878values. It is possible to configure the daemon to serve custom documents
8879instead of the ones provided with GNUnet, by setting the @code{HTMLDIR} value
8880in its configuration to a directory path.
8881
8882Within the provided path, the daemon will search for these three files:
8883
8884@itemize @bullet
8885@item fcfsd-index.html
8886@item fcfsd-notfound.html
8887@item fcfsd-forbidden.html
8888@end itemize
8889
8890The @file{fcfsd-index.html} file is the daemon's ``homepage'': operators might
8891want to provide information about the service here, or provide a form with
8892which it is possible to register a name.
8893
8894The @file{fcfsd-notfound.html} file is used primarily to let users know they
8895tried to access an unknown endpoint.
8896
8897The @file{fcfsd-forbidden.html} file is served to users when they try to
8898access an endpoint they should not access. For example, sending an invalid
8899request might result in this page being served.
8900
8901@cindex GNS Namecache
8902@node GNS Namecache
8903@section GNS Namecache
8904
8905The NAMECACHE subsystem is responsible for caching (encrypted) resolution
8906results of the GNU Name System (GNS). GNS makes zone information available
8907to other users via the DHT. However, as accessing the DHT for every
8908lookup is expensive (and as the DHT's local cache is lost whenever the
8909peer is restarted), GNS uses the NAMECACHE as a more persistent cache for
8910DHT lookups.
8911Thus, instead of always looking up every name in the DHT, GNS first
8912checks if the result is already available locally in the NAMECACHE.
8913Only if there is no result in the NAMECACHE, GNS queries the DHT.
8914The NAMECACHE stores data in the same (encrypted) format as the DHT.
8915It thus makes no sense to iterate over all items in the
8916NAMECACHE --- the NAMECACHE does not have a way to provide the keys
8917required to decrypt the entries.
8918
8919Blocks in the NAMECACHE share the same expiration mechanism as blocks in
8920the DHT --- the block expires wheneever any of the records in
8921the (encrypted) block expires.
8922The expiration time of the block is the only information stored in
8923plaintext. The NAMECACHE service internally performs all of the required
8924work to expire blocks, clients do not have to worry about this.
8925Also, given that NAMECACHE stores only GNS blocks that local users
8926requested, there is no configuration option to limit the size of the
8927NAMECACHE. It is assumed to be always small enough (a few MB) to fit on
8928the drive.
8929
8930The NAMECACHE supports the use of different database backends via a
8931plugin API.
8932
8933@menu
8934* libgnunetnamecache::
8935* The NAMECACHE Client-Service Protocol::
8936* The NAMECACHE Plugin API::
8937@end menu
8938
8939@node libgnunetnamecache
8940@subsection libgnunetnamecache
8941
8942
8943
8944The NAMECACHE API consists of five simple functions. First, there is
8945@code{GNUNET_NAMECACHE_connect} to connect to the NAMECACHE service.
8946This returns the handle required for all other operations on the
8947NAMECACHE. Using @code{GNUNET_NAMECACHE_block_cache} clients can insert a
8948block into the cache.
8949@code{GNUNET_NAMECACHE_lookup_block} can be used to lookup blocks that
8950were stored in the NAMECACHE. Both operations can be canceled using
8951@code{GNUNET_NAMECACHE_cancel}. Note that canceling a
8952@code{GNUNET_NAMECACHE_block_cache} operation can result in the block
8953being stored in the NAMECACHE --- or not. Cancellation primarily ensures
8954that the continuation function with the result of the operation will no
8955longer be invoked.
8956Finally, @code{GNUNET_NAMECACHE_disconnect} closes the connection to the
8957NAMECACHE.
8958
8959The maximum size of a block that can be stored in the NAMECACHE is
8960@code{GNUNET_NAMECACHE_MAX_VALUE_SIZE}, which is defined to be 63 kB.
8961
8962@node The NAMECACHE Client-Service Protocol
8963@subsection The NAMECACHE Client-Service Protocol
8964
8965
8966
8967All messages in the NAMECACHE IPC protocol start with the
8968@code{struct GNUNET_NAMECACHE_Header} which adds a request
8969ID (32-bit integer) to the standard message header.
8970The request ID is used to match requests with the
8971respective responses from the NAMECACHE, as they are allowed to happen
8972out-of-order.
8973
8974
8975@menu
8976* Lookup::
8977* Store::
8978@end menu
8979
8980@node Lookup
8981@subsubsection Lookup
8982
8983
8984
8985The @code{struct LookupBlockMessage} is used to lookup a block stored in
8986the cache.
8987It contains the query hash. The NAMECACHE always responds with a
8988@code{struct LookupBlockResponseMessage}. If the NAMECACHE has no
8989response, it sets the expiration time in the response to zero.
8990Otherwise, the response is expected to contain the expiration time, the
8991ECDSA signature, the derived key and the (variable-size) encrypted data
8992of the block.
8993
8994@node Store
8995@subsubsection Store
8996
8997
8998
8999The @code{struct BlockCacheMessage} is used to cache a block in the
9000NAMECACHE.
9001It has the same structure as the @code{struct LookupBlockResponseMessage}.
9002The service responds with a @code{struct BlockCacheResponseMessage} which
9003contains the result of the operation (success or failure).
9004In the future, we might want to make it possible to provide an error
9005message as well.
9006
9007@node The NAMECACHE Plugin API
9008@subsection The NAMECACHE Plugin API
9009
9010
9011The NAMECACHE plugin API consists of two functions, @code{cache_block} to
9012store a block in the database, and @code{lookup_block} to lookup a block
9013in the database.
9014
9015
9016@menu
9017* Lookup2::
9018* Store2::
9019@end menu
9020
9021@node Lookup2
9022@subsubsection Lookup2
9023
9024
9025
9026The @code{lookup_block} function is expected to return at most one block
9027to the iterator, and return @code{GNUNET_NO} if there were no non-expired
9028results.
9029If there are multiple non-expired results in the cache, the lookup is
9030supposed to return the result with the largest expiration time.
9031
9032@node Store2
9033@subsubsection Store2
9034
9035
9036
9037The @code{cache_block} function is expected to try to store the block in
9038the database, and return @code{GNUNET_SYSERR} if this was not possible
9039for any reason.
9040Furthermore, @code{cache_block} is expected to implicitly perform cache
9041maintenance and purge blocks from the cache that have expired. Note that
9042@code{cache_block} might encounter the case where the database already has
9043another block stored under the same key. In this case, the plugin must
9044ensure that the block with the larger expiration time is preserved.
9045Obviously, this can done either by simply adding new blocks and selecting
9046for the most recent expiration time during lookup, or by checking which
9047block is more recent during the store operation.
9048
9049@cindex REVOCATION Subsystem
9050@node REVOCATION Subsystem
9051@section REVOCATION Subsystem
9052
9053
9054The REVOCATION subsystem is responsible for key revocation of Egos.
9055If a user learns that their private key has been compromised or has lost
9056it, they can use the REVOCATION system to inform all of the other users
9057that their private key is no longer valid.
9058The subsystem thus includes ways to query for the validity of keys and to
9059propagate revocation messages.
9060
9061@menu
9062* Dissemination::
9063* Revocation Message Design Requirements::
9064* libgnunetrevocation::
9065* The REVOCATION Client-Service Protocol::
9066* The REVOCATION Peer-to-Peer Protocol::
9067@end menu
9068
9069@node Dissemination
9070@subsection Dissemination
9071
9072
9073
9074When a revocation is performed, the revocation is first of all
9075disseminated by flooding the overlay network.
9076The goal is to reach every peer, so that when a peer needs to check if a
9077key has been revoked, this will be purely a local operation where the
9078peer looks at its local revocation list. Flooding the network is also the
9079most robust form of key revocation --- an adversary would have to control
9080a separator of the overlay graph to restrict the propagation of the
9081revocation message. Flooding is also very easy to implement --- peers that
9082receive a revocation message for a key that they have never seen before
9083simply pass the message to all of their neighbours.
9084
9085Flooding can only distribute the revocation message to peers that are
9086online.
9087In order to notify peers that join the network later, the revocation
9088service performs efficient set reconciliation over the sets of known
9089revocation messages whenever two peers (that both support REVOCATION
9090dissemination) connect.
9091The SET service is used to perform this operation efficiently.
9092
9093@node Revocation Message Design Requirements
9094@subsection Revocation Message Design Requirements
9095
9096
9097
9098However, flooding is also quite costly, creating O(|E|) messages on a
9099network with |E| edges.
9100Thus, revocation messages are required to contain a proof-of-work, the
9101result of an expensive computation (which, however, is cheap to verify).
9102Only peers that have expended the CPU time necessary to provide
9103this proof will be able to flood the network with the revocation message.
9104This ensures that an attacker cannot simply flood the network with
9105millions of revocation messages. The proof-of-work required by GNUnet is
9106set to take days on a typical PC to compute; if the ability to quickly
9107revoke a key is needed, users have the option to pre-compute revocation
9108messages to store off-line and use instantly after their key has expired.
9109
9110Revocation messages must also be signed by the private key that is being
9111revoked. Thus, they can only be created while the private key is in the
9112possession of the respective user. This is another reason to create a
9113revocation message ahead of time and store it in a secure location.
9114
9115@node libgnunetrevocation
9116@subsection libgnunetrevocation
9117
9118
9119
9120The REVOCATION API consists of two parts, to query and to issue
9121revocations.
9122
9123
9124@menu
9125* Querying for revoked keys::
9126* Preparing revocations::
9127* Issuing revocations::
9128@end menu
9129
9130@node Querying for revoked keys
9131@subsubsection Querying for revoked keys
9132
9133
9134
9135@code{GNUNET_REVOCATION_query} is used to check if a given ECDSA public
9136key has been revoked.
9137The given callback will be invoked with the result of the check.
9138The query can be canceled using @code{GNUNET_REVOCATION_query_cancel} on
9139the return value.
9140
9141@node Preparing revocations
9142@subsubsection Preparing revocations
9143
9144
9145
9146It is often desirable to create a revocation record ahead-of-time and
9147store it in an off-line location to be used later in an emergency.
9148This is particularly true for GNUnet revocations, where performing the
9149revocation operation itself is computationally expensive and thus is
9150likely to take some time.
9151Thus, if users want the ability to perform revocations quickly in an
9152emergency, they must pre-compute the revocation message.
9153The revocation API enables this with two functions that are used to
9154compute the revocation message, but not trigger the actual revocation
9155operation.
9156
9157@code{GNUNET_REVOCATION_check_pow} should be used to calculate the
9158proof-of-work required in the revocation message. This function takes the
9159public key, the required number of bits for the proof of work (which in
9160GNUnet is a network-wide constant) and finally a proof-of-work number as
9161arguments.
9162The function then checks if the given proof-of-work number is a valid
9163proof of work for the given public key. Clients preparing a revocation
9164are expected to call this function repeatedly (typically with a
9165monotonically increasing sequence of numbers of the proof-of-work number)
9166until a given number satisfies the check.
9167That number should then be saved for later use in the revocation
9168operation.
9169
9170@code{GNUNET_REVOCATION_sign_revocation} is used to generate the
9171signature that is required in a revocation message.
9172It takes the private key that (possibly in the future) is to be revoked
9173and returns the signature.
9174The signature can again be saved to disk for later use, which will then
9175allow performing a revocation even without access to the private key.
9176
9177@node Issuing revocations
9178@subsubsection Issuing revocations
9179
9180
9181Given a ECDSA public key, the signature from @code{GNUNET_REVOCATION_sign}
9182and the proof-of-work,
9183@code{GNUNET_REVOCATION_revoke} can be used to perform the
9184actual revocation. The given callback is called upon completion of the
9185operation. @code{GNUNET_REVOCATION_revoke_cancel} can be used to stop the
9186library from calling the continuation; however, in that case it is
9187undefined whether or not the revocation operation will be executed.
9188
9189@node The REVOCATION Client-Service Protocol
9190@subsection The REVOCATION Client-Service Protocol
9191
9192
9193The REVOCATION protocol consists of four simple messages.
9194
9195A @code{QueryMessage} containing a public ECDSA key is used to check if a
9196particular key has been revoked. The service responds with a
9197@code{QueryResponseMessage} which simply contains a bit that says if the
9198given public key is still valid, or if it has been revoked.
9199
9200The second possible interaction is for a client to revoke a key by passing a
9201@code{RevokeMessage} to the service. The @code{RevokeMessage} contains the
9202ECDSA public key to be revoked, a signature by the corresponding private key
9203and the proof-of-work. The service responds with a
9204@code{RevocationResponseMessage} which can be used to indicate that the
9205@code{RevokeMessage} was invalid (e.g. the proof of work is incorrect), or
9206otherwise to indicate that the revocation has been processed successfully.
9207
9208@node The REVOCATION Peer-to-Peer Protocol
9209@subsection The REVOCATION Peer-to-Peer Protocol
9210
9211
9212
9213Revocation uses two disjoint ways to spread revocation information among
9214peers.
9215First of all, P2P gossip exchanged via CORE-level neighbours is used to
9216quickly spread revocations to all connected peers.
9217Second, whenever two peers (that both support revocations) connect,
9218the SET service is used to compute the union of the respective revocation
9219sets.
9220
9221In both cases, the exchanged messages are @code{RevokeMessage}s which
9222contain the public key that is being revoked, a matching ECDSA signature,
9223and a proof-of-work.
9224Whenever a peer learns about a new revocation this way, it first
9225validates the signature and the proof-of-work, then stores it to disk
9226(typically to a file $GNUNET_DATA_HOME/revocation.dat) and finally
9227spreads the information to all directly connected neighbours.
9228
9229For computing the union using the SET service, the peer with the smaller
9230hashed peer identity will connect (as a "client" in the two-party set
9231protocol) to the other peer after one second (to reduce traffic spikes
9232on connect) and initiate the computation of the set union.
9233All revocation services use a common hash to identify the SET operation
9234over revocation sets.
9235
9236The current implementation accepts revocation set union operations from
9237all peers at any time; however, well-behaved peers should only initiate
9238this operation once after establishing a connection to a peer with a
9239larger hashed peer identity.
9240
9241@cindex FS
9242@cindex FS Subsystem
9243@node File-sharing (FS) Subsystem
9244@section File-sharing (FS) Subsystem
9245
9246
9247
9248This chapter describes the details of how the file-sharing service works.
9249As with all services, it is split into an API (libgnunetfs), the service
9250process (gnunet-service-fs) and user interface(s).
9251The file-sharing service uses the datastore service to store blocks and
9252the DHT (and indirectly datacache) for lookups for non-anonymous
9253file-sharing.
9254Furthermore, the file-sharing service uses the block library (and the
9255block fs plugin) for validation of DHT operations.
9256
9257In contrast to many other services, libgnunetfs is rather complex since
9258the client library includes a large number of high-level abstractions;
9259this is necessary since the Fs service itself largely only operates on
9260the block level.
9261The FS library is responsible for providing a file-based abstraction to
9262applications, including directories, meta data, keyword search,
9263verification, and so on.
9264
9265The method used by GNUnet to break large files into blocks and to use
9266keyword search is called the
9267"Encoding for Censorship Resistant Sharing" (ECRS).
9268ECRS is largely implemented in the fs library; block validation is also
9269reflected in the block FS plugin and the FS service.
9270ECRS on-demand encoding is implemented in the FS service.
9271
9272NOTE: The documentation in this chapter is quite incomplete.
9273
9274@menu
9275* Encoding for Censorship-Resistant Sharing (ECRS)::
9276* File-sharing persistence directory structure::
9277@end menu
9278
9279@cindex ECRS
9280@cindex Encoding for Censorship-Resistant Sharing
9281@node Encoding for Censorship-Resistant Sharing (ECRS)
9282@subsection Encoding for Censorship-Resistant Sharing (ECRS)
9283
9284
9285
9286When GNUnet shares files, it uses a content encoding that is called ECRS,
9287the Encoding for Censorship-Resistant Sharing.
9288Most of ECRS is described in the (so far unpublished) research paper
9289attached to this page. ECRS obsoletes the previous ESED and ESED II
9290encodings which were used in GNUnet before version 0.7.0.
9291The rest of this page assumes that the reader is familiar with the
9292attached paper. What follows is a description of some minor extensions
9293that GNUnet makes over what is described in the paper.
9294The reason why these extensions are not in the paper is that we felt
9295that they were obvious or trivial extensions to the original scheme and
9296thus did not warrant space in the research report.
9297
9298@menu
9299* Namespace Advertisements::
9300* KSBlocks::
9301@end menu
9302
9303@node Namespace Advertisements
9304@subsubsection Namespace Advertisements
9305
9306
9307@c %**FIXME: all zeroses -> ?
9308
9309An @code{SBlock} with identifier all zeros is a signed
9310advertisement for a namespace. This special @code{SBlock} contains
9311metadata describing the content of the namespace.
9312Instead of the name of the identifier for a potential update, it contains
9313the identifier for the root of the namespace.
9314The URI should always be empty. The @code{SBlock} is signed with the
9315content provider's RSA private key (just like any other SBlock). Peers
9316can search for @code{SBlock}s in order to find out more about a namespace.
9317
9318@node KSBlocks
9319@subsubsection KSBlocks
9320
9321
9322
9323GNUnet implements @code{KSBlocks} which are @code{KBlocks} that, instead
9324of encrypting a CHK and metadata, encrypt an @code{SBlock} instead.
9325In other words, @code{KSBlocks} enable GNUnet to find @code{SBlocks}
9326using the global keyword search.
9327Usually the encrypted @code{SBlock} is a namespace advertisement.
9328The rationale behind @code{KSBlock}s and @code{SBlock}s is to enable
9329peers to discover namespaces via keyword searches, and, to associate
9330useful information with namespaces. When GNUnet finds @code{KSBlocks}
9331during a normal keyword search, it adds the information to an internal
9332list of discovered namespaces. Users looking for interesting namespaces
9333can then inspect this list, reducing the need for out-of-band discovery
9334of namespaces.
9335Naturally, namespaces (or more specifically, namespace advertisements) can
9336also be referenced from directories, but @code{KSBlock}s should make it
9337easier to advertise namespaces for the owner of the pseudonym since they
9338eliminate the need to first create a directory.
9339
9340Collections are also advertised using @code{KSBlock}s.
9341
9342@c https://old.gnunet.org/sites/default/files/ecrs.pdf
9343
9344@node File-sharing persistence directory structure
9345@subsection File-sharing persistence directory structure
9346
9347
9348
9349This section documents how the file-sharing library implements
9350persistence of file-sharing operations and specifically the resulting
9351directory structure.
9352This code is only active if the @code{GNUNET_FS_FLAGS_PERSISTENCE} flag
9353was set when calling @code{GNUNET_FS_start}.
9354In this case, the file-sharing library will try hard to ensure that all
9355major operations (searching, downloading, publishing, unindexing) are
9356persistent, that is, can live longer than the process itself.
9357More specifically, an operation is supposed to live until it is
9358explicitly stopped.
9359
9360If @code{GNUNET_FS_stop} is called before an operation has been stopped, a
9361@code{SUSPEND} event is generated and then when the process calls
9362@code{GNUNET_FS_start} next time, a @code{RESUME} event is generated.
9363Additionally, even if an application crashes (segfault, SIGKILL, system
9364crash) and hence @code{GNUNET_FS_stop} is never called and no
9365@code{SUSPEND} events are generated, operations are still resumed (with
9366@code{RESUME} events).
9367This is implemented by constantly writing the current state of the
9368file-sharing operations to disk.
9369Specifically, the current state is always written to disk whenever
9370anything significant changes (the exception are block-wise progress in
9371publishing and unindexing, since those operations would be slowed down
9372significantly and can be resumed cheaply even without detailed
9373accounting).
9374Note that if the process crashes (or is killed) during a serialization
9375operation, FS does not guarantee that this specific operation is
9376recoverable (no strict transactional semantics, again for performance
9377reasons). However, all other unrelated operations should resume nicely.
9378
9379Since we need to serialize the state continuously and want to recover as
9380much as possible even after crashing during a serialization operation,
9381we do not use one large file for serialization.
9382Instead, several directories are used for the various operations.
9383When @code{GNUNET_FS_start} executes, the master directories are scanned
9384for files describing operations to resume.
9385Sometimes, these operations can refer to related operations in child
9386directories which may also be resumed at this point.
9387Note that corrupted files are cleaned up automatically.
9388However, dangling files in child directories (those that are not
9389referenced by files from the master directories) are not automatically
9390removed.
9391
9392Persistence data is kept in a directory that begins with the "STATE_DIR"
9393prefix from the configuration file
9394(by default, "$SERVICEHOME/persistence/") followed by the name of the
9395client as given to @code{GNUNET_FS_start} (for example, "gnunet-gtk")
9396followed by the actual name of the master or child directory.
9397
9398The names for the master directories follow the names of the operations:
9399
9400@itemize @bullet
9401@item "search"
9402@item "download"
9403@item "publish"
9404@item "unindex"
9405@end itemize
9406
9407Each of the master directories contains names (chosen at random) for each
9408active top-level (master) operation.
9409Note that a download that is associated with a search result is not a
9410top-level operation.
9411
9412In contrast to the master directories, the child directories are only
9413consulted when another operation refers to them.
9414For each search, a subdirectory (named after the master search
9415synchronization file) contains the search results.
9416Search results can have an associated download, which is then stored in
9417the general "download-child" directory.
9418Downloads can be recursive, in which case children are stored in
9419subdirectories mirroring the structure of the recursive download
9420(either starting in the master "download" directory or in the
9421"download-child" directory depending on how the download was initiated).
9422For publishing operations, the "publish-file" directory contains
9423information about the individual files and directories that are part of
9424the publication.
9425However, this directory structure is flat and does not mirror the
9426structure of the publishing operation.
9427Note that unindex operations cannot have associated child operations.
9428
9429@cindex REGEX subsystem
9430@node REGEX Subsystem
9431@section REGEX Subsystem
9432
9433
9434
9435Using the REGEX subsystem, you can discover peers that offer a particular
9436service using regular expressions.
9437The peers that offer a service specify it using a regular expressions.
9438Peers that want to patronize a service search using a string.
9439The REGEX subsystem will then use the DHT to return a set of matching
9440offerers to the patrons.
9441
9442For the technical details, we have Max's defense talk and Max's Master's
9443thesis.
9444
9445@c An additional publication is under preparation and available to
9446@c team members (in Git).
9447@c FIXME: Where is the file? Point to it. Assuming that it's szengel2012ms
9448
9449@menu
9450* How to run the regex profiler::
9451@end menu
9452
9453@node How to run the regex profiler
9454@subsection How to run the regex profiler
9455
9456
9457
9458The gnunet-regex-profiler can be used to profile the usage of mesh/regex
9459for a given set of regular expressions and strings.
9460Mesh/regex allows you to announce your peer ID under a certain regex and
9461search for peers matching a particular regex using a string.
9462See @uref{https://bib.gnunet.org/full/date.html#2012_5f2, szengel2012ms} for a full
9463introduction.
9464
9465First of all, the regex profiler uses GNUnet testbed, thus all the
9466implications for testbed also apply to the regex profiler
9467(for example you need password-less ssh login to the machines listed in
9468your hosts file).
9469
9470@strong{Configuration}
9471
9472Moreover, an appropriate configuration file is needed.
9473Generally you can refer to the
9474@file{contrib/regex_profiler_infiniband.conf} file in the sourcecode
9475of GNUnet for an example configuration.
9476In the following paragraph the important details are highlighted.
9477
9478Announcing of the regular expressions is done by the
9479gnunet-daemon-regexprofiler, therefore you have to make sure it is
9480started, by adding it to the START_ON_DEMAND set of ARM:
9481
9482@example
9483[regexprofiler]
9484START_ON_DEMAND = YES
9485@end example
9486
9487@noindent
9488Furthermore you have to specify the location of the binary:
9489
9490@example
9491[regexprofiler]
9492# Location of the gnunet-daemon-regexprofiler binary.
9493BINARY = /home/szengel/gnunet/src/mesh/.libs/gnunet-daemon-regexprofiler
9494# Regex prefix that will be applied to all regular expressions and
9495# search string.
9496REGEX_PREFIX = "GNVPN-0001-PAD"
9497@end example
9498
9499@noindent
9500When running the profiler with a large scale deployment, you probably
9501want to reduce the workload of each peer.
9502Use the following options to do this.
9503
9504@example
9505[dht]
9506# Force network size estimation
9507FORCE_NSE = 1
9508
9509[dhtcache]
9510DATABASE = heap
9511# Disable RC-file for Bloom filter? (for benchmarking with limited IO
9512# availability)
9513DISABLE_BF_RC = YES
9514# Disable Bloom filter entirely
9515DISABLE_BF = YES
9516
9517[nse]
9518# Minimize proof-of-work CPU consumption by NSE
9519WORKBITS = 1
9520@end example
9521
9522@noindent
9523@strong{Options}
9524
9525To finally run the profiler some options and the input data need to be
9526specified on the command line.
9527
9528@example
9529gnunet-regex-profiler -c config-file -d log-file -n num-links \
9530-p path-compression-length -s search-delay -t matching-timeout \
9531-a num-search-strings hosts-file policy-dir search-strings-file
9532@end example
9533
9534@noindent
9535Where...
9536
9537@itemize @bullet
9538@item ... @code{config-file} means the configuration file created earlier.
9539@item ... @code{log-file} is the file where to write statistics output.
9540@item ... @code{num-links} indicates the number of random links between
9541started peers.
9542@item ... @code{path-compression-length} is the maximum path compression
9543length in the DFA.
9544@item ... @code{search-delay} time to wait between peers finished linking
9545and starting to match strings.
9546@item ... @code{matching-timeout} timeout after which to cancel the
9547searching.
9548@item ... @code{num-search-strings} number of strings in the
9549search-strings-file.
9550@item ... the @code{hosts-file} should contain a list of hosts for the
9551testbed, one per line in the following format:
9552
9553@itemize @bullet
9554@item @code{user@@host_ip:port}
9555@end itemize
9556@item ... the @code{policy-dir} is a folder containing text files
9557containing one or more regular expressions. A peer is started for each
9558file in that folder and the regular expressions in the corresponding file
9559are announced by this peer.
9560@item ... the @code{search-strings-file} is a text file containing search
9561strings, one in each line.
9562@end itemize
9563
9564@noindent
9565You can create regular expressions and search strings for every AS in the
9566Internet using the attached scripts. You need one of the
9567@uref{http://data.caida.org/datasets/routing/routeviews-prefix2as/, CAIDA routeviews prefix2as}
9568data files for this. Run
9569
9570@example
9571create_regex.py <filename> <output path>
9572@end example
9573
9574@noindent
9575to create the regular expressions and
9576
9577@example
9578create_strings.py <input path> <outfile>
9579@end example
9580
9581@noindent
9582to create a search strings file from the previously created
9583regular expressions.
9584
9585@cindex REST subsystem
9586@node REST Subsystem
9587@section REST Subsystem
9588
9589
9590
9591Using the REST subsystem, you can expose REST-based APIs or services.
9592The REST service is designed as a pluggable architecture.
9593To create a new REST endpoint, simply add a library in the form
9594``plugin_rest_*''.
9595The REST service will automatically load all REST plugins on startup.
9596
9597@strong{Configuration}
9598
9599The REST service can be configured in various ways.
9600The reference config file can be found in
9601@file{src/rest/rest.conf}:
9602@example
9603[rest]
9604REST_PORT=7776
9605REST_ALLOW_HEADERS=Authorization,Accept,Content-Type
9606REST_ALLOW_ORIGIN=*
9607REST_ALLOW_CREDENTIALS=true
9608@end example
9609
9610The port as well as
9611@deffn{cross-origin resource sharing} (CORS)
9612@end deffn
9613headers that are supposed to be advertised by the rest service are
9614configurable.
9615
9616@menu
9617* Namespace considerations::
9618* Endpoint documentation::
9619@end menu
9620
9621@node Namespace considerations
9622@subsection Namespace considerations
9623
9624The @command{gnunet-rest-service} will load all plugins that are installed.
9625As such it is important that the endpoint namespaces do not clash.
9626
9627For example, plugin X might expose the endpoint ``/xxx'' while plugin Y
9628exposes endpoint ``/xxx/yyy''.
9629This is a problem if plugin X is also supposed to handle a call
9630to ``/xxx/yyy''.
9631Currently the REST service will not complain or warn about such clashes,
9632so please make sure that endpoints are unambiguous.
9633
9634@node Endpoint documentation
9635@subsection Endpoint documentation
9636
9637This is WIP. Endpoints should be documented appropriately.
9638Preferably using annotations.
9639
9640
9641@cindex RPS Subsystem
9642@node RPS Subsystem
9643@section RPS Subsystem
9644
9645In literature, Random Peer Sampling (RPS) refers to the problem of
9646reliably@footnote{"Reliable" in this context means having no bias,
9647neither spatial, nor temporal, nor through malicious activity.} drawing
9648random samples from an unstructured p2p network.
9649
9650Doing so in a reliable manner is not only hard because of inherent
9651problems but also because of possible malicious peers that could try to
9652bias the selection.
9653
9654It is useful for all kind of gossip protocols that require the selection
9655of random peers in the whole network like gathering statistics,
9656spreading and aggregating information in the network, load balancing and
9657overlay topology management.
9658
9659The approach chosen in the RPS service implementation in GNUnet follows
9660the @uref{https://bib.gnunet.org/full/date.html\#2009_5f0, Brahms}
9661design.
9662
9663The current state is "work in progress". There are a lot of things that
9664need to be done, primarily finishing the experimental evaluation and a
9665re-design of the API.
9666
9667The abstract idea is to subscribe to connect to/start the RPS service
9668and request random peers that will be returned when they represent a
9669random selection from the whole network with high probability.
9670
9671An additional feature to the original Brahms-design is the selection of
9672sub-groups: The GNUnet implementation of RPS enables clients to ask for
9673random peers from a group that is defined by a common shared secret.
9674(The secret could of course also be public, depending on the use-case.)
9675
9676Another addition to the original protocol was made: The sampler
9677mechanism that was introduced in Brahms was slightly adapted and used to
9678actually sample the peers and returned to the client.
9679This is necessary as the original design only keeps peers connected to
9680random other peers in the network. In order to return random peers to
9681client requests independently random, they cannot be drawn from the
9682connected peers.
9683The adapted sampler makes sure that each request for random peers is
9684independent from the others.
9685
9686@menu
9687* Brahms::
9688@end menu
9689
9690@node Brahms
9691@subsection Brahms
9692The high-level concept of Brahms is two-fold: Combining push-pull gossip
9693with locally fixing a assumed bias using cryptographic min-wise
9694permutations.
9695The central data structure is the view - a peer's current local sample.
9696This view is used to select peers to push to and pull from.
9697This simple mechanism can be biased easily. For this reason Brahms
9698'fixes' the bias by using the so-called sampler. A data structure that
9699takes a list of elements as input and outputs a random one of them
9700independently of the frequency in the input set. Both an element that
9701was put into the sampler a single time and an element that was put into
9702it a million times have the same probability of being the output.
9703This is achieved with exploiting min-wise independent
9704permutations.
9705In the RPS service we use HMACs: On the initialisation of a sampler
9706element, a key is chosen at random. On each input the HMAC with the
9707random key is computed. The sampler element keeps the element with the
9708minimal HMAC.
9709
9710In order to fix the bias in the view, a fraction of the elements in the
9711view are sampled through the sampler from the random stream of peer IDs.
9712
9713According to the theoretical analysis of Bortnikov et al. this suffices
9714to keep the network connected and having random peers in the view.
9715
9716@cindex TRANSPORT-NG Subsystem
9717@node TRANSPORT-NG Subsystem
9718@section TRANSPORT-NG Subsystem
9719
9720The current GNUnet TRANSPORT architecture is rooted in the GNUnet 0.4 design
9721of using plugins for the actual transmission operations and the ATS subsystem
9722to select a plugin and allocate bandwidth. The following key issues have been
9723identified with this design:
9724
9725@itemize @bullet
9726@item Bugs in one plugin can affect the TRANSPORT service and other plugins.
9727 There is at least one open bug that affects sockets, where the origin is
9728 difficult to pinpoint due to the large code base.
9729@item Relevant operating system default configurations often impose a limit of
9730 1024 file descriptors per process. Thus, one plugin may impact other
9731 plugin's connectivity choices.
9732@item Plugins are required to offer bi-directional connectivity. However,
9733 firewalls (incl. NAT boxes) and physical environments sometimes only
9734 allow uni-directional connectivity, which then currently cannot be
9735 utilized at all.
9736@item Distance vector routing was implemented in 209 but shortly afterwards
9737 broken and due to the complexity of implementing it as a plugin and
9738 dealing with the resource allocation consequences was never useful.
9739@item Most existing plugins communicate completely using cleartext, exposing
9740 metad data (message size) and making it easy to fingerprint and
9741 possibly block GNUnet traffic.
9742@item Various NAT traversal methods are not supported.
9743@item The service logic is cluttered with "manipulation" support code for
9744 TESTBED to enable faking network characteristics like lossy connections
9745 or firewewalls.
9746@item Bandwidth allocation is done in ATS, requiring the duplication of state
9747 and resulting in much delayed allocation decisions. As a result,
9748 often available bandwidth goes unused. Users are expected to manually
9749 configure bandwidth limits, instead of TRANSPORT using congestion control
9750 to adapt automatically.
9751@item TRANSPORT is difficult to test and has bad test coverage.
9752@item HELLOs include an absolute expiration time. Nodes with unsynchronized
9753 clocks cannot connect.
9754@item Displaying the contents of a HELLO requires the respective plugin as the
9755 plugin-specific data is encoded in binary. This also complicates logging.
9756@end itemize
9757
9758
9759@menu
9760* Design goals of TNG::
9761* HELLO-NG::
9762* Priorities and preferences::
9763* Communicators::
9764@end menu
9765
9766@node Design goals of TNG
9767@subsection Design goals of TNG
9768
9769In order to address the above issues, we want to:
9770
9771@itemize @bullet
9772@item Move plugins into separate processes which we shall call
9773 @emph{communicators}. Communicators connect as clients to the transport
9774 service.
9775@item TRANSPORT should be able to utilize any number of communcators to the
9776 same peer at the same time.
9777@item TRANSPORT should be responsible for fragmentation, retransmission,
9778 flow- and congestion-control. Users should no longer have to configure
9779 bandwidth limits: TRANSPORT should detect what is available and use it.
9780@item Commnunicators should be allowed to be uni-directional and unreliable.
9781 TRANSPORT shall create bi-directional channels from this whenever
9782 possible.
9783@item DV should no longer be a plugin, but part of TRANSPORT.
9784@item TRANSPORT should provide communicators help communicating, for example
9785 in the case of uni-directional communicators or the need for out-of-band
9786 signalling for NAT traversal. We call this functionality
9787 @emph{backchannels}.
9788@item Transport manipulation should be signalled to CORE on a per-message basis
9789 instead of an approximate bandwidth.
9790@item CORE should signal performance requirements (reliability, latency, etc.)
9791 on a per-message basis to TRANSPORT. If possible, TRANSPORT should
9792 consider those options when scheduling messages for transmission.
9793@item HELLOs should be in a humman-readable format with monotonic time
9794 expirations.
9795@end itemize
9796
9797The new architecture is planned as follows:
9798
9799
9800@image{images/tng,5in,,TNG architecture.}
9801
9802TRANSPORT's main objective is to establish bi-directional virtual links using a
9803variety of possibly uni-directional communicators. Links undergo the following
9804steps:
9805
9806@enumerate
9807@item Communicator informs TRANSPORT A that a queue (direct neighbour) is
9808 available, or equivalently TRANSPORT A discovers a (DV) path to a target
9809 B.
9810@item TRANSPORT A sends a challenge to the target peer, trying to confirm that
9811 the peer can receive. FIXME: This is not implemented properly for DV.
9812 Here we should really take a validated DVH and send a challenge exactly
9813 down that path!
9814@item The other TRANSPORT, TRANSPORT B, receives the challenge, and sends back
9815 a response, possibly using a dierent path. If TRANSPORT B does not yet
9816 have a virtual link to A, it must try to establish a virtual link.
9817@item Upon receiving the response, TRANSPORT A creates the virtual link. If the
9818 response included a challenge, TRANSPORT A must respond to this challenge
9819 as well, eectively re-creating the TCP 3-way handshake (just with longer
9820 challenge values).
9821@end enumerate
9822
9823@node HELLO-NG
9824@subsection HELLO-NG
9825
9826HELLOs change in three ways. First of all, communicators encode the respective
9827addresses in a human-readable URL-like string. This way, we do no longer
9828require the communicator to print the contents of a HELLO.
9829Second, HELLOs no longer contain an expiration time, only a creation time.
9830The receiver must only compare the respective absolute values. So given a HELLO
9831from the same sender with a larger creation time, then the old one is no longer
9832valid. This also obsoletes the need for the gnunet-hello binary to set HELLO
9833expiration times to never.
9834Third, a peer no longer generates one big HELLO that always contains all of the
9835addresses. Instead, each address is signed individually and shared only over
9836the address scopes where it makes sense to share the address. In particular,
9837care should be taken to not share MACs across the Internet and confine their
9838use to the LAN.
9839As each address is signed separately, having multiple addresses valid at the
9840same time (given the new creation time expiration logic) requires that those
9841addresses must have exactly the same creation time.
9842Whenever that monotonic time is increased, all addresses must be re-signed and
9843re-distributed.
9844
9845@node Priorities and preferences
9846@subsection Priorities and preferences
9847
9848In the new design, TRANSPORT adopts a feature (which was previously already
9849available in CORE) of the MQ API to allow applications to specify priorities and
9850preferences per message (or rather, per MQ envelope).
9851The (updated) MQ API allows applications to specify one of four priority levels
9852as well as desired preferences for transmission by setting options on an
9853envelope. These preferences currently are:
9854
9855@itemize @bullet
9856@item GNUNET_MQ_PREF_UNRELIABLE: Disables TRANSPORT waiting for ACKS on
9857 unreliable channels like UDP. Now it is fire and forget. These messages
9858 then cannot be used for RTT estimates either.
9859@item GNUNET_MQ_PREF_LOW_LATENCY: Directs TRANSPORT to select the
9860 lowest-latency transmission choices possible.
9861@item GNUNET_MQ_PREF_CORK_ALLOWED: Allows TRANSPORT to delay transmission to
9862 group the message with other messages into a larger batch to reduce the
9863 number of packets sent.
9864@item GNUNET_MQ_PREF_GOODPUT: Directs TRANSPORT to select the highest goodput
9865 channel available.
9866@item GNUNET_MQ_PREF_OUT_OF_ORDER: Allows TRANSPORT to reorder the messages as
9867 it sees fit, otherwise TRANSPORT should attempt to preserve transmission
9868 order.
9869@end itemize
9870
9871Each MQ envelope is always able to store those options (and the priority), and
9872in the future this uniform API will be used by TRANSPORT, CORE, CADET and
9873possibly other subsystems that send messages (like LAKE).
9874When CORE sets preferences and priorities, it is supposed to respect the
9875preferences and priorities it is given from higher layers. Similarly, CADET also
9876simply passes on the preferences and priorities of the layer above CADET. When a
9877layer combines multiple smaller messages into one larger transmission, the
9878@code{GNUNET_MQ_env_combine_options()} should be used to calculate options for
9879the combined message. We note that the exact semantics of the options may differ
9880by layer. For example, CADET will always strictly implement reliable and
9881in-order delivery of messages, while the same options are only advisory for
9882TRANSPORT and CORE: they should try (using ACKs on unreliable communicators,
9883not changing the message order themselves), but if messages are lost anyway
9884(e.g. because a TCP is dropped in the middle), or if messages are reordered
9885(e.g. because they took different paths over the network and arrived in a
9886different order) TRANSPORT and CORE do not have to correct this. Whether a
9887preference is strict or loose is thus dened by the respective layer.
9888
9889@node Communicators
9890@subsection Communicators
9891
9892The API for communicators is defined in
9893@code{gnunet_transport_communication_service.h}.
9894Each communicator must specify its (global) communication characteristics, which
9895for now only say whether the communication is reliable (e.g. TCP, HTTPS) or
9896unreliable (e.g. UDP, WLAN). Each communicator must specify a unique address
9897prex, or NULL if the communicator cannot establish outgoing connections
9898(for example because it is only acting as a TCP server).
9899A communicator must tell TRANSPORT which addresses it is reachable under.
9900Addresses may be added or removed at any time. A communicator may have zero
9901addresses (transmission only).
9902Addresses do not have to match the address prefix.
9903
9904TRANSPORT may ask a communicator to try to connect to another address.
9905TRANSPORT will only ask for connections where the address matches the
9906communicator's address prefix that was provided when the connection was
9907established. Communicators should then attempt to establish a connection.
9908No response is provided to TRANSPORT service on failure. The TRANSPORT service
9909has to ask the communicator explicitly to retry.
9910
9911If a communicator succeeds in establishing an outgoing connection for
9912transmission, or if a communicator receives an incoming bi-directional
9913connection, the communicator must inform the TRANSPORT service that a message
9914queue (MQ) for transmission is now available. For that MQ, the communicator must
9915provide the peer identity claimed by the other end, a human-readable address
9916(for debugging) and a maximum transfer unit (MTU). A MTU of zero means sending
9917is not supported, SIZE_MAX should be used for no MTU. The communicator should
9918also tell TRANSPORT what network type is used for the queue. The communicator
9919may tell TRANSPORT anytime that the queue was deleted and is no longer
9920available.
9921
9922The communicator API also provides for flow control. First, communicators
9923exhibit back-pressure on TRANSPORT: the number of messages TRANSPORT may add to
9924a queue for transmission will be limited. So by not draining the transmission
9925queue, back-pressure is provided to TRANSPORT. In the other direction,
9926communicators may allow TRANSPORT to give back-pressure towards the
9927communicator by providing a non-NULL
9928@code{GNUNET_TRANSPORT_MessageCompletedCallback}
9929argument to the @code{GNUNET_TRANSPORT_communicator_receive} function. In this
9930case, TRANSPORT will only invoke this function once it has processed the message
9931and is ready to receive more. Communicators should then limit how much traffic
9932they receive based on this backpressure. Note that communicators do not have to
9933provide a @code{GNUNET_TRANSPORT_MessageCompletedCallback};
9934for example, UDP cannot support back-pressure due to the nature of the UDP
9935protocol. In this case, TRANSPORT will implement its own TRANSPORT-to-TRANSPORT
9936flow control to reduce the sender's data rate to acceptable levels.
9937
9938TRANSPORT may notify a communicator about backchannel messages TRANSPORT
9939received from other peers for this communicator. Similarly, communicators can
9940ask TRANSPORT to try to send a backchannel message to other communicators of
9941other peers. The semantics of the backchannel message are up to the
9942communicators which use them.
9943TRANSPORT may fail transmitting backchannel messages, and TRANSPORT will not
9944attempt to retransmit them.
9945
9946@cindex MESSENGER Subsystem
9947@cindex MESSENGER
9948@cindex messenger
9949@node MESSENGER Subsystem
9950@section MESSENGER Subsystem
9951
9952The MESSENGER subsystem is responsible for secure end-to-end communication in
9953groups of nodes in the GNUnet overlay network. MESSENGER builds on the CADET
9954subsystem which provides a reliable and secure end-to-end communication between
9955the nodes inside of these groups.
9956
9957Additionally to the CADET security benefits, MESSENGER provides following
9958properties designed for application level usage:
9959
9960@itemize @bullet
9961@item MESSENGER provides integrity by signing the messages with the users
9962 provided ego
9963@item MESSENGER adds (optional) forward secrecy by replacing the key pair of the
9964 used ego and signing the propagation of the new one with old one (chaining
9965 egos)
9966@item MESSENGER provides verification of a original sender by checking against
9967 all used egos from a member which are currently in active use (active use
9968 depends on the state of a member session)
9969@item MESSENGER offsers (optional) decentralized message forwarding between all
9970 nodes in a group to improve availability and prevent MITM-attacks
9971@item MESSENGER handles new connections and disconnections from nodes in the
9972 group by reconnecting them preserving an efficient structure for message
9973 distribution (ensuring availability and accountablity)
9974@item MESSENGER provides replay protection (messages can be uniquely identified
9975 via SHA-512, include a timestamp and the hash of the last message)
9976@item MESSENGER allows detection for dropped messages by chaining them (messages
9977 refer to the last message by their hash) improving accountability
9978@item MESSENGER allows requesting messages from other peers explicitly to ensure
9979 availability
9980@item MESSENGER provides confidentiality by padding messages to few different
9981 sizes (512 bytes, 4096 bytes, 32768 bytes and maximal message size from
9982 CADET)
9983@item MESSENGER adds (optional) confidentiality with ECDHE to exchange and use
9984 symmetric encryption, encrypting with both AES-256 and Twofish but
9985 allowing only selected members to decrypt (using the receivers ego for
9986 ECDHE)
9987@end itemize
9988
9989Also MESSENGER provides multiple features with privacy in mind:
9990
9991@itemize @bullet
9992@item MESSENGER allows deleting messages from all peers in the group by the
9993 original sender (uses the MESSENGER provided verification)
9994@item MESSENGER allows using the publicly known anonymous ego instead of any
9995 unique identifying ego
9996@item MESSENGER allows your node to decide between acting as host of the used
9997 messaging room (sharing your peer's identity with all nodes in the group)
9998 or acting as guest (sharing your peer's identity only with the nodes you
9999 explicitly open a connection to)
10000@item MESSENGER handles members independently of the peer's identity making
10001 forwarded messages indistinguishable from directly received ones (
10002 complicating the tracking of messages and identifying its origin)
10003@item MESSENGER allows names of members being not unique (also names are
10004 optional)
10005@item MESSENGER does not include information about the selected receiver of an
10006 explicitly encrypted message in its header, complicating it for other
10007 members to draw conclusions from communication partners
10008@end itemize
10009
10010@menu
10011* libgnunetmessenger::
10012* Member sessions::
10013@end menu
10014
10015@node libgnunetmessenger
10016@subsection libgnunetmessenger
10017
10018The MESSENGER API (defined in @file{gnunet_messenger_service.h}) allows P2P
10019applications built using GNUnet to communicate with specified kinds of messages
10020in a group. It provides applications the ability to send and receive encrypted
10021messages to any group of peers participating in GNUnet in a decentralized way (
10022without even knowing all peers's identities).
10023
10024MESSENGER delivers messages to other peers in "rooms". A room uses a variable
10025amount of CADET "channels" which will all be used for message distribution. Each
10026channel can represent an outgoing connection opened by entering a room with
10027@code{GNUNET_MESSENGER_enter_room} or an incoming connection if the room was
10028opened before via @code{GNUNET_MESSENGER_open_room}.
10029
10030@image{images/messenger_room,6in,,Room structure}
10031
10032To enter a room you have to specify the "door" (peer's identity of a peer which
10033has opened the room) and the key of the room (which is identical to a CADET
10034"port"). To open a room you have to specify only the key to use. When opening a
10035room you automatically distribute a PEER-message sharing your peer's identity in
10036the room.
10037
10038Entering or opening a room can also be combined in any order. In any case you
10039will automatically get a unique member ID and send a JOIN-message notifying
10040others about your entry and your public key from your selected ego.
10041
10042The ego can be selected by name with the initial @code{GNUNET_MESSENGER_connect}
10043besides setting a (identity-)callback for each change/confirmation of the used
10044ego and a (message-)callback which gets called every time a message gets sent or
10045received in the room. Once the identity-callback got called you can check your
10046used ego with @code{GNUNET_MESSENGER_get_key} providing only its public key. The
10047function returns NULL if the anonymous ego is used. If the ego should be
10048replaced with a newly generated one, you can use @code{GNUNET_MESSENGER_update}
10049to ensure proper chaining of used egos.
10050
10051Also once the identity-callback got called you can check your used name with
10052@code{GNUNET_MESSENGER_get_name} and potentially change or set a name via
10053@code{GNUNET_MESSENGER_set_name}. A name is for example required to create a new
10054ego with @code{GNUNET_MESSENGER_update}. Also any change in ego or name will
10055automatically be distributed in the room with a NAME- or KEY-message
10056respectively.
10057
10058To send a message a message inside of a room you can use
10059@code{GNUNET_MESSENGER_send_message}. If you specify a selected contact as
10060receiver, the message gets encrypted automatically and will be sent as PRIVATE-
10061message instead.
10062
10063To request a potentially missed message or to get a specific message after its
10064original call of the message-callback, you can use
10065@code{GNUNET_MESSENGER_get_message}. Additionally once a message was distributed
10066to application level and the message-callback got called, you can get the
10067contact respresenting a message's sender respectively with
10068@code{GNUNET_MESSENGER_get_sender}. This allows getting name and the public key
10069of any sender currently in use with @code{GNUNET_MESSENGER_contact_get_name}
10070and @code{GNUNET_MESSENGER_contact_get_key}. It is also possible to iterate
10071through all current members of a room with
10072@code{GNUNET_MESSENGER_iterate_members} using a callback.
10073
10074To leave a room you can use @code{GNUNET_MESSENGER_close_room} which will also
10075close the rooms connections once all applications on the same peer have left
10076the room. Leaving a room will also send a LEAVE-message closing a member session
10077on all connected peers before any connection will be closed. Leaving a room is
10078however not required for any application to keep your member session open
10079between multiple sessions of the actual application.
10080
10081Finally, when an application no longer wants to use CADET, it should call
10082@code{GNUNET_MESSENGER_disconnect}. You don't have to explicitly close the used
10083rooms or leave them.
10084
10085Here is a little summary to the kinds of messages you can send manually:
10086
10087@menu
10088* MERGE-message::
10089* INVITE-message::
10090* TEXT-message::
10091* FILE-message::
10092* DELETE-message::
10093@end menu
10094
10095@node MERGE-message
10096@subsubsection MERGE-message
10097
10098MERGE-messages will generally be sent automatically to reduce the amount of
10099parallel chained messages. This is necessary to close a member session for
10100example. You can also send MERGE-messages manually if required to merge two
10101chains of messages.
10102
10103@node INVITE-message
10104@subsubsection INVITE-message
10105
10106INVITE-messages can be used to invite other members in a room to a different
10107room, sharing one potential door and the required key to enter the room. This
10108kind of message is typically sent as encrypted PRIVATE-message to selected
10109members because it doesn't make much sense to invite all members from one room
10110to another considering a rooms key doesn't specify its usage.
10111
10112@node TEXT-message
10113@subsubsection TEXT-message
10114
10115TEXT-messages can be used to send simple text-based messages and should be
10116considered as being in readable form without complex decoding. The text has to
10117end with a NULL-terminator character and should be in UTF-8 encoding for most
10118compatibility.
10119
10120@node FILE-message
10121@subsubsection FILE-message
10122
10123FILE-messages can be used to share files inside of a room. They do not contain
10124the actual file being shared but its original hash, filename, URI to download
10125the file and a symmetric key to decrypt the downloaded file.
10126
10127It is recommended to use the FS subsystem and the FILE-messages in combination.
10128
10129@node DELETE-message
10130@subsubsection DELETE-message
10131
10132DELETE-messages can be used to delete messages selected with its hash. You can
10133also select any custom delay relative to the time of sending the DELETE-message.
10134Deletion will only be processed on each peer in a room if the sender is
10135authorized.
10136
10137The only information of a deleted message which being kept will be the chained
10138hashes connecting the message graph for potential traversion. For example the
10139check for completion of a member session requires this information.
10140
10141@node Member sessions
10142@subsection Member sessions
10143
10144A member session is a triple of the room key, the member ID and the public key
10145of the member's ego. Member sessions allow that a member can change their ID or
10146their ego once at a time without losing the ability to delete old messages or
10147identifying the original sender of a message. On every change of ID or EGO a
10148session will be marked as closed. So every session chain will only contain one
10149open session with the current ID and public key.
10150
10151If a session is marked as closed the MESSENGER service will check from the first
10152message opening a session to its last one closing the session for completion. If
10153a the service can confirm that there is no message still missing which was sent
10154from the closed member session, it will be marked as completed.
10155
10156A completed member session is not able to verify any incoming message to ensure
10157forward secrecy preventing others from using old stolen egos.