("gnurl" ,gnurl)
("gstreamer" ,gstreamer)
("gst-plugins-base" ,gst-plugins-base)
- ("gnutls" ,gnutls) ;Change to gnutls/dane once it is merged.
+ ("gnutls/dane" ,gnutls/dane)
("libextractor" ,libextractor)
("libgcrypt" ,libgcrypt)
("libidn" ,libidn)
("mysql" ,mysql)
("zlib" ,zlib)
("perl" ,perl)
- ("python" ,python) ; tests and gnunet-qr
+ ("python-2" ,python-2) ; tests and gnunet-qr
("jansson" ,jansson)
("nss" ,nss)
("glib" ,glib "bin")
(zero? (system* "sh" "bootstrap"))))
(replace 'build
(lambda _
- (chdir "doc")
+ (chdir "doc/documentation")
(zero? (system* "make" "pdf"))
(zero? (system* "make" "html"))
(zero? (system* "make" "info"))))
# This Makefile.am is in the public domain
-SUBDIRS = man doxygen
-
-docdir = $(datadir)/doc/gnunet/
-
-infoimagedir = $(infodir)/images
-
-#DOT_FILES = images/$(wildcard *.dot)
-
-#DOT_VECTOR_GRAPHICS = \
-# $(DOT_FILES:%.dot=%.eps) \
-# $(DOT_FILES:%.dot=%.pdf)
-
-AM_MAKEINFOHTMLFLAGS = --no-split --css-ref=docstyle.css
-
-dist_infoimage_DATA = \
- images/gnunet-gtk-0-10-gns-a-done.png \
- images/gnunet-gtk-0-10-gns-a.png \
- images/daemon_lego_block.png \
- images/gnunet-gtk-0-10-gns.png \
- images/gnunet-0-10-peerinfo.png \
- images/gnunet-gtk-0-10-identity.png \
- images/gnunet-fs-gtk-0-10-star-tab.png \
- images/gnunet-gtk-0-10.png \
- images/gnunet-gtk-0-10-download-area.png \
- images/gnunet-gtk-0-10-search-selected.png \
- images/gnunet-gtk-0-10-fs-menu.png \
- images/gnunet-gtk-0-10-traffic.png \
- images/gnunet-gtk-0-10-fs.png \
- images/gnunet-namestore-gtk-phone.png \
- images/gnunet-gtk-0-10-fs-publish-editing.png \
- images/gnunet-namestore-gtk-vpn.png \
- images/gnunet-gtk-0-10-fs-published.png \
- images/gnunet-setup-exit.png \
- images/gnunet-gtk-0-10-fs-publish.png \
- images/iceweasel-preferences.png \
- images/gnunet-gtk-0-10-fs-publish-select.png \
- images/iceweasel-proxy.png \
- images/gnunet-gtk-0-10-fs-publish-with-file_0.png \
- images/service_lego_block.png \
- images/gnunet-gtk-0-10-fs-publish-with-file.png \
- images/service_stack.png \
- images/gnunet-gtk-0-10-fs-search.png \
- images/gnunet-tutorial-service.png \
- images/gnunet-tutorial-system.png \
- images/daemon_lego_block.svg \
- images/lego_stack.svg \
- images/service_lego_block.svg \
- images/structure.dot
-
-# images/$(wildcard *.png) \
-# images/$(wildcard *.svg)
-# $(DOT_FILES:%.dot=%.png)
-
-#DOT_OPTIONS = \
-# -Gratio=.9 -Gnodesep=.005 -Granksep=.00005 \
-# -Nfontsite=9 -Nheight=.1 -Nwidth=.1
-
-# .dot.png:
-# $(AM_V_DOT)$(DOT) -Tpng $(DOT_OPTIONS) < "$<" > "$(srcdir)/$@.tmp"; \
-# mv "$(srcdir)/$@.tmp" "$(srcdir)/$@"
-
-# .dot.pdf:
-# $(AM_V_DOT)$(DOT) -Tpdf $(DOT_OPTIONS) < "$<" > "$(srcdir)/$@.tmp"; \
-# mv "$(srcdir)/$@.tmp" "$(srcdir)/$@"
-
-# .dot.eps:
-# $(AM_V_DOT)$(DOT) -Teps $(DOT_OPTIONS) < "$<" > "$(srcdir)/$@.tmp"; \
-# mv "$(srcdir)/$@.tmp" "$(srcdir)/$@"
-
-# .png.eps:
-# $(AM_V_GEN)convert "$<" "$@-tmp.eps"; \
-# mv "$@-tmp.eps" "$@"
-
-# pdf-local: $(DOT_FILES=%.dot=$(top_srcdir)/%.pdf)
-# info-local: $(DOT_FILES=%.dot=$(top_srcdir)/%.png)
-# ps-local: $(DOT_FILES=%.dot=$(top_srcdir)/%.eps) \
-# $(top_srcdir)/%D%/images/coreutils-size-map.eps
-# dvi-local: ps-local
-
-gnunet_tutorial_examples = \
- 001.c \
- 002.c \
- 003.c \
- 004.c \
- 005.c \
- 006.c \
- 007.c \
- 008.c \
- 009.c \
- 010.c \
- 011.c \
- 012.c \
- 013.c \
- 013.1.c \
- 014.c \
- 015.c \
- 016.c \
- 017.c \
- 018.c \
- 019.c \
- 020.c \
- 021.c \
- 022.c \
- 023.c \
- 024.c \
- 025.c \
- 026.c
-
-info_TEXINFOS = \
- gnunet.texi \
- gnunet-c-tutorial.texi
-
-gnunet_TEXINFOS = \
- chapters/developer.texi \
- chapters/installation.texi \
- chapters/philosophy.texi \
- chapters/user.texi \
- chapters/vocabulary.texi \
- fdl-1.3.texi \
- gpl-3.0.texi
+SUBDIRS = man doxygen documentation
EXTRA_DIST = \
- $(gnunet_TEXINFOS) \
outdated-and-old-installation-instructions.txt \
gnunet-c-tutorial-v1.pdf \
- $(gnunet_tutorial_examples) \
- README.txt \
- docstyle.css
-
-
-# $(DOT_FILES) \
-# $(DOT_VECTOR_GRAPHICS)
-
-DISTCLEANFILES = \
- gnunet.cps \
- gnunet-c-tutorial.cps \
- chapters/developer.cps \
- chapters/installation.cps \
- chapter/philosophy.cps \
- chapters/user.cps \
- fdl-1.3.cps \
- gpl-3.0.cps
-
-# if HAVE_EXTENDED_DOCUMENTATION_BUILDING
-daemon_lego_block.png: images/daemon_lego_block.svg
- convert images/daemon_lego_block.svg images/daemon_lego_block.png &&
- pngcrush images/daemon_lego_block.png images/daemon_lego_block.png
-
-service_lego_block.png: images/service_lego_block.svg
- convert images/service_lego_block.svg images/service_lego_block.png &&
- pngcrush images/service_lego_block.png images/serivce_lego_block.png
-
-lego_stack.png: images/lego_stack.svg
- convert images/lego_stack.svg images/lego_stack.png &&
- pngcrush images/lego_stack.png images/lego_stack.png
-
-# FIXME: The usage of 'date' strings causes a warning.
-# version.texi:
-# echo "@set UPDATED $(date +'%d %B %Y')" > $@
-# echo "@set UPDATED-MONTH $(date +'%B %Y')" >> $@
-# echo "@set EDITION $(PACKAGE_VERSION)" >> $@
-# echo "@set VERSION $(PACKAGE_VERSION)" >> $@
-
-# Workaround for makeinfo error. Whcih in turn introduces more
-# date-related 'warnings'. Well.
-version2.texi:
- echo "@set UPDATED $(date +'%d %B %Y')" > $@
- echo "@set UPDATED-MONTH $(date +'%B %Y')" >> $@
- echo "@set EDITION $(PACKAGE_VERSION)" >> $@
- echo "@set VERSION $(PACKAGE_VERSION)" >> $@
-
-# FIXME: rm *.html and *.pdf
-#doc-clean:
-# @rm *.aux *.log *.toc *.cp *.cps
-
-doc-all-install:
- @mkdir -p $(DESTDIR)/$(docdir)
- @mkdir -p $(DESTDIR)/$(infoimagedir)
- @mkdir -p $(DESTDIR)/$(infodir)
- @install -m 0755 gnunet.pdf $(DESTDIR)/$(docdir)
- @install -m 0755 gnunet-c-tutorial.pdf $(DESTDIR)/$(docdir)
- @install -m 0755 gnunet-c-tutorial.info $(DESTDIR)/$(infodir)
- @install -m 0755 gnunet.info $(DESTDIR)/$(infodir)
- @install gnunet.html $(DESTDIR)/$(docdir)
- @install gnunet-c-tutorial.html $(DESTDIR)/$(docdir)
-
-# @cp -r images $(DESTDIR)/$(infoimagedir)
-
-# TODO: Add more to clean.
-clean:
- @rm gnunet.pdf
- @rm gnunet.html
- @rm gnunet.info
- @rm gnunet.info-1
- @rm gnunet.info-2
- @rm gnunet.info-3
- @rm gnunet-c-tutorial.pdf
- @rm gnunet-c-tutorial.info
- @rm gnunet-c-tutorial.html
- @rm -r gnunet.t2p
- @rm -r gnunet-c-tutorial.t2p
-
-# CLEANFILES = \
-# gnunet.log \
-# gnunet-c-tutorial.log \
-# $(wildcard *.aux) \
-# $(wildcard *.toc) \
-# $(wildcard *.cp) \
-# $(wildcard *.cps)
-
-#.PHONY: version.texi
-# if HAVE_EXTENDED_DOCUMENTATION_BUILDING_PDF
-
-# if HAVE_EXTENDED_DOCUMENTATION_BUILDING_HTML
-
-# endif
-# endif
-# endif
+ README.txt
+++ /dev/null
-To be moved to an appropriate section of "how to write documentation" or
-"how to contribute to the documentation":
-
-1. When writing documentation, please use gender-neutral wording when
- referring to people, such as singular “they”, “their”, “them”, and
- so forth. -> https://en.wikipedia.org/wiki/Singular_they
-
-2. Keep line length below 74 characters.
-
-3. Do not use tab characters (see chapter 2.1 texinfo manual)
-* What's left to do
-
-- Which Texlive modules are needed? Decrease the size.
-- Update the content of gnunet documentation.
-
-* How to use (hack) on this
-
-** with guix
-
-Adjust accordingly, ie read the Guix Documentation:
-setenv GUIX_PACKAGE_PATH "gnunet/contrib/packages/guix/packages"
-guix environment gnunet-doc
-and
-guix build -f contrib/packages/guix/gnunet-doc.scm
-
-** without guix
-
-You need to have Texinfo and Texlive in your path.
-sh bootstrap
-./configure --enable-documentation
-cd doc
-make (format you want)
-
-for example: make html, make info, make pdf
-
-* structure (relations)
-
-** gnunet.texi
- -> chapters/developer.texi
- -> chapters/installation.texi
- -> chapters/philosophy.texi
- -> chapters/user.texi
- -> chapters/vocabulary.texi
- -> images/*
- -> gpl-3.0.texi
- -> fdl-1.3.texi
-
-** gnunet-c-tutorial.texi
- -> figs/Service.pdf
- -> figs/System.pdf
- -> tutorial-examples/*.c
- -> gpl-3.0.texi
- -> fdl-1.3.texi
-
-- gnunet-c-tutorial-v1.pdf: original LaTeX "gnunet-c-tutorial.pdf".
-- man folder: the man pages.
-- doxygen folder
-- outdated-and-old-installation-instructions.txt: self described within the file.
-
-
-Use `gendocs', add to the manual/ directory of the web site.
-
- $ cd doc
- $ gendocs.sh gnunet "GNUnet 0.10.X Reference Manual"
+++ /dev/null
-@c ***********************************************************************
-@node GNUnet Developer Handbook
-@chapter GNUnet Developer Handbook
-
-This book is intended to be an introduction for programmers that want to
-extend the GNUnet framework. GNUnet is more than a simple peer-to-peer
-application. For developers, GNUnet is:
-
-@itemize @bullet
-@item Free software under the GNU General Public License, with a community
-that believes in the GNU philosophy
-@item
-A set of standards, including coding conventions and architectural rules
-@item
-A set of layered protocols, both specifying the communication between
-peers as well as the communication between components of a single peer.
-@item
-A set of libraries with well-defined APIs suitable for writing extensions
-@end itemize
-
-In particular, the architecture specifies that a peer consists of many
-processes communicating via protocols. Processes can be written in almost
-any language. C and Java APIs exist for accessing existing services and
-for writing extensions. It is possible to write extensions in other
-languages by implementing the necessary IPC protocols.
-
-GNUnet can be extended and improved along many possible dimensions, and
-anyone interested in free software and freedom-enhancing networking is
-welcome to join the effort. This developer handbook attempts to provide
-an initial introduction to some of the key design choices and central
-components of the system. This manual is far from complete, and we
-welcome informed contributions, be it in the form of new chapters or
-insightful comments.
-
-However, the website is experiencing a constant onslaught of sophisticated
-link-spam entered manually by exploited workers solving puzzles and
-customizing text. To limit this commercial defacement, we are strictly
-moderating comments and have disallowed "normal" users from posting new
-content. However, this is really only intended to keep the spam at bay. If
-you are a real user or aspiring developer, please drop us a note
-(IRC, e-mail, contact form) with your user profile ID number included.
-We will then relax these restrictions on your account. We're sorry for
-this inconvenience; however, few people would want to read this site
-if 99% of it was advertisements for bogus websites.
-
-
-
-@c ***********************************************************************
-
-
-
-
-
-
-
-
-@menu
-* Developer Introduction::
-* Code overview::
-* System Architecture::
-* Subsystem stability::
-* Naming conventions and coding style guide::
-* Build-system::
-* Developing extensions for GNUnet using the gnunet-ext template::
-* Writing testcases::
-* GNUnet's TESTING library::
-* Performance regression analysis with Gauger::
-* GNUnet's TESTBED Subsystem::
-* libgnunetutil::
-* The Automatic Restart Manager (ARM)::
-* GNUnet's TRANSPORT Subsystem::
-* NAT library::
-* Distance-Vector plugin::
-* SMTP plugin::
-* Bluetooth plugin::
-* WLAN plugin::
-* The ATS Subsystem::
-* GNUnet's CORE Subsystem::
-* GNUnet's CADET subsystem::
-* GNUnet's NSE subsystem::
-* GNUnet's HOSTLIST subsystem::
-* GNUnet's IDENTITY subsystem::
-* GNUnet's NAMESTORE Subsystem::
-* GNUnet's PEERINFO subsystem::
-* GNUnet's PEERSTORE subsystem::
-* GNUnet's SET Subsystem::
-* GNUnet's STATISTICS subsystem::
-* GNUnet's Distributed Hash Table (DHT)::
-* The GNU Name System (GNS)::
-* The GNS Namecache::
-* The REVOCATION Subsystem::
-* GNUnet's File-sharing (FS) Subsystem::
-* GNUnet's REGEX Subsystem::
-@end menu
-
-@node Developer Introduction
-@section Developer Introduction
-
-This developer handbook is intended as first introduction to GNUnet for
-new developers that want to extend the GNUnet framework. After the
-introduction, each of the GNUnet subsystems (directories in the
-@file{src/} tree) is (supposed to be) covered in its own chapter. In
-addition to this documentation, GNUnet developers should be aware of the
-services available on the GNUnet server to them.
-
-New developers can have a look a the GNUnet tutorials for C and java
-available in the @file{src/} directory of the repository or under the
-following links:
-
-@c ** FIXME: Link to files in source, not online.
-@c ** FIXME: Where is the Java tutorial?
-@itemize @bullet
-@item @uref{https://gnunet.org/git/gnunet.git/plain/doc/gnunet-c-tutoria
-l.pdf, GNUnet C tutorial}
-@item GNUnet Java tutorial
-@end itemize
-
-In addition to this book, the GNUnet server contains various resources for
-GNUnet developers. They are all conveniently reachable via the "Developer"
-entry in the navigation menu. Some additional tools (such as static
-analysis reports) require a special developer access to perform certain
-operations. If you feel you need access, you should contact
-@uref{http://grothoff.org/christian/, Christian Grothoff},
-GNUnet's maintainer.
-
-The public subsystems on the GNUnet server that help developers are:
-
-@itemize @bullet
-@item The Version control system keeps our code and enables distributed
-development. Only developers with write access can commit code, everyone
-else is encouraged to submit patches to the
-@uref{https://lists.gnu.org/mailman/listinfo/gnunet-developers,
-GNUnet-developers mailinglist}.
-@item The GNUnet bugtracking system is used to track feature requests,
-open bug reports and their resolutions. Anyone can report bugs, only
-developers can claim to have fixed them.
-@item A buildbot is used to check GNUnet builds automatically on a range
-of platforms. Builds are triggered automatically after 30 minutes of no
-changes to Git.
-@item The current quality of our automated test suite is assessed using
-Code coverage analysis. This analysis is run daily; however the webpage
-is only updated if all automated tests pass at that time. Testcases that
-improve our code coverage are always welcome.
-@item We try to automatically find bugs using a static analysis scan.
-This scan is run daily; however the webpage is only updated if all
-automated tests pass at the time. Note that not everything that is
-flagged by the analysis is a bug, sometimes even good code can be marked
-as possibly problematic. Nevertheless, developers are encouraged to at
-least be aware of all issues in their code that are listed.
-@item We use Gauger for automatic performance regression visualization.
-Details on how to use Gauger are here.
-@item We use @uref{http://junit.org/, junit} to automatically test
-gnunet-java. Automatically generated, current reports on the test suite
-are here.
-@item We use Cobertura to generate test coverage reports for gnunet-java.
-Current reports on test coverage are here.
-@end itemize
-
-
-
-@c ***********************************************************************
-@menu
-* Project overview::
-@end menu
-
-@node Project overview
-@subsection Project overview
-
-The GNUnet project consists at this point of several sub-projects. This
-section is supposed to give an initial overview about the various
-sub-projects. Note that this description also lists projects that are far
-from complete, including even those that have literally not a single line
-of code in them yet.
-
-GNUnet sub-projects in order of likely relevance are currently:
-
-@table @asis
-
-@item gnunet Core of the P2P framework, including file-sharing, VPN and
-chat applications; this is what the developer handbook covers mostly
-@item gnunet-gtk Gtk+-based user interfaces, including gnunet-fs-gtk
-(file-sharing), gnunet-statistics-gtk (statistics over time),
-gnunet-peerinfo-gtk (information about current connections and known
-peers), gnunet-chat-gtk (chat GUI) and gnunet-setup (setup tool for
-"everything")
-@item gnunet-fuse Mounting directories shared via GNUnet's file-sharing
-on Linux
-@item gnunet-update Installation and update tool
-@item gnunet-ext Template for starting 'external' GNUnet projects
-@item gnunet-java Java APIs for writing GNUnet services and applications
-@c ** FIXME: Point to new website repository once we have it:
-@c ** @item svn/gnunet-www/ Code and media helping drive the GNUnet
-website
-@item eclectic Code to run
-GNUnet nodes on testbeds for research, development, testing and evaluation
-@c ** FIXME: Solve the status and location of gnunet-qt
-@item gnunet-qt qt-based GNUnet GUI (dead?)
-@item gnunet-cocoa cocoa-based GNUnet GUI (dead?)
-
-@end table
-
-We are also working on various supporting libraries and tools:
-@c ** FIXME: What about gauger, and what about libmwmodem?
-
-@table @asis
-@item libextractor GNU libextractor (meta data extraction)
-@item libmicrohttpd GNU libmicrohttpd (embedded HTTP(S) server library)
-@item gauger Tool for performance regression analysis
-@item monkey Tool for automated debugging of distributed systems
-@item libmwmodem Library for accessing satellite connection quality
-reports
-@end table
-
-Finally, there are various external projects (see links for a list of
-those that have a public website) which build on top of the GNUnet
-framework.
-
-@c ***********************************************************************
-@node Code overview
-@section Code overview
-
-This section gives a brief overview of the GNUnet source code.
-Specifically, we sketch the function of each of the subdirectories in
-the @file{gnunet/src/} directory. The order given is roughly bottom-up
-(in terms of the layers of the system).
-
-@table @asis
-@item util/ --- libgnunetutil Library with general utility functions, all
-GNUnet binaries link against this library. Anything from memory
-allocation and data structures to cryptography and inter-process
-communication. The goal is to provide an OS-independent interface and
-more 'secure' or convenient implementations of commonly used primitives.
-The API is spread over more than a dozen headers, developers should study
-those closely to avoid duplicating existing functions.
-@item hello/ --- libgnunethello HELLO messages are used to
-describe under which addresses a peer can be reached (for example,
-protocol, IP, port). This library manages parsing and generating of HELLO
-messages.
-@item block/ --- libgnunetblock The DHT and other components of GNUnet
-store information in units called 'blocks'. Each block has a type and the
-type defines a particular format and how that binary format is to be
-linked to a hash code (the key for the DHT and for databases). The block
-library is a wapper around block plugins which provide the necessary
-functions for each block type.
-@item statistics/ The statistics service enables associating
-values (of type uint64_t) with a componenet name and a string. The main
-uses is debugging (counting events), performance tracking and user
-entertainment (what did my peer do today?).
-@item arm/ The automatic-restart-manager (ARM) service
-is the GNUnet master service. Its role is to start gnunet-services, to
-re-start them when they crashed and finally to shut down the system when
-requested.
-@item peerinfo/ The peerinfo service keeps track of which peers are known
-to the local peer and also tracks the validated addresses for each peer
-(in the form of a HELLO message) for each of those peers. The peer is not
-necessarily connected to all peers known to the peerinfo service.
-Peerinfo provides persistent storage for peer identities --- peers are
-not forgotten just because of a system restart.
-@item datacache/ --- libgnunetdatacache The datacache
-library provides (temporary) block storage for the DHT. Existing plugins
-can store blocks in Sqlite, Postgres or MySQL databases. All data stored
-in the cache is lost when the peer is stopped or restarted (datacache
-uses temporary tables).
-@item datastore/ The datastore service stores file-sharing blocks in
-databases for extended periods of time. In contrast to the datacache, data
-is not lost when peers restart. However, quota restrictions may still
-cause old, expired or low-priority data to be eventually discarded.
-Existing plugins can store blocks in Sqlite, Postgres or MySQL databases.
-@item template/ Template for writing a new service. Does nothing.
-@item ats/ The automatic transport
-selection (ATS) service is responsible for deciding which address (i.e.
-which transport plugin) should be used for communication with other peers,
-and at what bandwidth.
-@item nat/ --- libgnunetnat Library that provides basic
-functions for NAT traversal. The library supports NAT traversal with
-manual hole-punching by the user, UPnP and ICMP-based autonomous NAT
-traversal. The library also includes an API for testing if the current
-configuration works and the @code{gnunet-nat-server} which provides an
-external service to test the local configuration.
-@item fragmentation/ --- libgnunetfragmentation Some
-transports (UDP and WLAN, mostly) have restrictions on the maximum
-transfer unit (MTU) for packets. The fragmentation library can be used to
-break larger packets into chunks of at most 1k and transmit the resulting
-fragments reliabily (with acknowledgement, retransmission, timeouts,
-etc.).
-@item transport/ The transport service is responsible for managing the
-basic P2P communication. It uses plugins to support P2P communication
-over TCP, UDP, HTTP, HTTPS and other protocols.The transport service
-validates peer addresses, enforces bandwidth restrictions, limits the
-total number of connections and enforces connectivity restrictions (i.e.
-friends-only).
-@item peerinfo-tool/
-This directory contains the gnunet-peerinfo binary which can be used to
-inspect the peers and HELLOs known to the peerinfo service.
-@item core/ The core
-service is responsible for establishing encrypted, authenticated
-connections with other peers, encrypting and decrypting messages and
-forwarding messages to higher-level services that are interested in them.
-@item testing/ ---
-libgnunettesting The testing library allows starting (and stopping) peers
-for writing testcases.@
-It also supports automatic generation of configurations for peers
-ensuring that the ports and paths are disjoint. libgnunettesting is also
-the foundation for the testbed service
-@item testbed/ The testbed service is
-used for creating small or large scale deployments of GNUnet peers for
-evaluation of protocols. It facilitates peer depolyments on multiple
-hosts (for example, in a cluster) and establishing varous network
-topologies (both underlay and overlay).
-@item nse/ The network size estimation (NSE) service
-implements a protocol for (securely) estimating the current size of the
-P2P network.
-@item dht/ The distributed hash table (DHT) service provides a
-distributed implementation of a hash table to store blocks under hash
-keys in the P2P network.
-@item hostlist/ The hostlist service allows learning about
-other peers in the network by downloading HELLO messages from an HTTP
-server, can be configured to run such an HTTP server and also implements
-a P2P protocol to advertise and automatically learn about other peers
-that offer a public hostlist server.
-@item topology/ The topology service is responsible for
-maintaining the mesh topology. It tries to maintain connections to friends
-(depending on the configuration) and also tries to ensure that the peer
-has a decent number of active connections at all times. If necessary, new
-connections are added. All peers should run the topology service,
-otherwise they may end up not being connected to any other peer (unless
-some other service ensures that core establishes the required
-connections). The topology service also tells the transport service which
-connections are permitted (for friend-to-friend networking)
-@item fs/ The file-sharing (FS) service implements GNUnet's
-file-sharing application. Both anonymous file-sharing (using gap) and
-non-anonymous file-sharing (using dht) are supported.
-@item cadet/ The CADET
-service provides a general-purpose routing abstraction to create
-end-to-end encrypted tunnels in mesh networks. We wrote a paper
-documenting key aspects of the design.
-@item tun/ --- libgnunettun Library for building IPv4, IPv6
-packets and creating checksums for UDP, TCP and ICMP packets. The header
-defines C structs for common Internet packet formats and in particular
-structs for interacting with TUN (virtual network) interfaces.
-@item mysql/ ---
-libgnunetmysql Library for creating and executing prepared MySQL
-statements and to manage the connection to the MySQL database.
-Essentially a lightweight wrapper for the interaction between GNUnet
-components and libmysqlclient.
-@item dns/ Service that allows intercepting and modifying DNS requests of
-the local machine. Currently used for IPv4-IPv6 protocol translation
-(DNS-ALG) as implemented by "pt/" and for the GNUnet naming system. The
-service can also be configured to offer an exit service for DNS traffic.
-@item vpn/ The virtual
-public network (VPN) service provides a virtual tunnel interface (VTUN)
-for IP routing over GNUnet. Needs some other peers to run an "exit"
-service to work.
-Can be activated using the "gnunet-vpn" tool or integrated with DNS using
-the "pt" daemon.
-@item exit/ Daemon to allow traffic from the VPN to exit this
-peer to the Internet or to specific IP-based services of the local peer.
-Currently, an exit service can only be restricted to IPv4 or IPv6, not to
-specific ports and or IP address ranges. If this is not acceptable,
-additional firewall rules must be added manually. exit currently only
-works for normal UDP, TCP and ICMP traffic; DNS queries need to leave the
-system via a DNS service.
-@item pt/ protocol translation daemon. This daemon enables 4-to-6,
-6-to-4, 4-over-6 or 6-over-4 transitions for the local system. It
-essentially uses "DNS" to intercept DNS replies and then maps results to
-those offered by the VPN, which then sends them using mesh to some daemon
-offering an appropriate exit service.
-@item identity/ Management of egos (alter egos) of a user; identities are
-essentially named ECC private keys and used for zones in the GNU name
-system and for namespaces in file-sharing, but might find other uses later
-@item revocation/ Key revocation service, can be used to revoke the
-private key of an identity if it has been compromised
-@item namecache/ Cache
-for resolution results for the GNU name system; data is encrypted and can
-be shared among users, loss of the data should ideally only result in a
-performance degradation (persistence not required)
-@item namestore/ Database
-for the GNU name system with per-user private information, persistence
-required
-@item gns/ GNU name system, a GNU approach to DNS and PKI.
-@item dv/ A plugin
-for distance-vector (DV)-based routing. DV consists of a service and a
-transport plugin to provide peers with the illusion of a direct P2P
-connection for connections that use multiple (typically up to 3) hops in
-the actual underlay network.
-@item regex/ Service for the (distributed) evaluation of
-regular expressions.
-@item scalarproduct/ The scalar product service offers an
-API to perform a secure multiparty computation which calculates a scalar
-product between two peers without exposing the private input vectors of
-the peers to each other.
-@item consensus/ The consensus service will allow a set
-of peers to agree on a set of values via a distributed set union
-computation.
-@item rest/ The rest API allows access to GNUnet services using RESTful
-interaction. The services provide plugins that can exposed by the rest
-server.
-@item experimentation/ The experimentation daemon coordinates distributed
-experimentation to evaluate transport and ats properties
-@end table
-
-@c ***********************************************************************
-@node System Architecture
-@section System Architecture
-
-GNUnet developers like legos. The blocks are indestructible, can be
-stacked together to construct complex buildings and it is generally easy
-to swap one block for a different one that has the same shape. GNUnet's
-architecture is based on legos:
-
-@c images here
-
-This chapter documents the GNUnet lego system, also known as GNUnet's
-system architecture.
-
-The most common GNUnet component is a service. Services offer an API (or
-several, depending on what you count as "an API") which is implemented as
-a library. The library communicates with the main process of the service
-using a service-specific network protocol. The main process of the service
-typically doesn't fully provide everything that is needed --- it has holes
-to be filled by APIs to other services.
-
-A special kind of component in GNUnet are user interfaces and daemons.
-Like services, they have holes to be filled by APIs of other services.
-Unlike services, daemons do not implement their own network protocol and
-they have no API:
-
-The GNUnet system provides a range of services, daemons and user
-interfaces, which are then combined into a layered GNUnet instance (also
-known as a peer).
-
-Note that while it is generally possible to swap one service for another
-compatible service, there is often only one implementation. However,
-during development we often have a "new" version of a service in parallel
-with an "old" version. While the "new" version is not working, developers
-working on other parts of the service can continue their development by
-simply using the "old" service. Alternative design ideas can also be
-easily investigated by swapping out individual components. This is
-typically achieved by simply changing the name of the "BINARY" in the
-respective configuration section.
-
-Key properties of GNUnet services are that they must be separate
-processes and that they must protect themselves by applying tight error
-checking against the network protocol they implement (thereby achieving a
-certain degree of robustness).
-
-On the other hand, the APIs are implemented to tolerate failures of the
-service, isolating their host process from errors by the service. If the
-service process crashes, other services and daemons around it should not
-also fail, but instead wait for the service process to be restarted by
-ARM.
-
-
-@c ***********************************************************************
-@node Subsystem stability
-@section Subsystem stability
-
-This page documents the current stability of the various GNUnet
-subsystems. Stability here describes the expected degree of compatibility
-with future versions of GNUnet. For each subsystem we distinguish between
-compatibility on the P2P network level (communication protocol between
-peers), the IPC level (communication between the service and the service
-library) and the API level (stability of the API). P2P compatibility is
-relevant in terms of which applications are likely going to be able to
-communicate with future versions of the network. IPC communication is
-relevant for the implementation of language bindings that re-implement the
-IPC messages. Finally, API compatibility is relevant to developers that
-hope to be able to avoid changes to applications build on top of the APIs
-of the framework.
-
-The following table summarizes our current view of the stability of the
-respective protocols or APIs:
-
-@multitable @columnfractions .20 .20 .20 .20
-@headitem Subsystem @tab P2P @tab IPC @tab C API
-@item util @tab n/a @tab n/a @tab stable
-@item arm @tab n/a @tab stable @tab stable
-@item ats @tab n/a @tab unstable @tab testing
-@item block @tab n/a @tab n/a @tab stable
-@item cadet @tab testing @tab testing @tab testing
-@item consensus @tab experimental @tab experimental @tab experimental
-@item core @tab stable @tab stable @tab stable
-@item datacache @tab n/a @tab n/a @tab stable
-@item datastore @tab n/a @tab stable @tab stable
-@item dht @tab stable @tab stable @tab stable
-@item dns @tab stable @tab stable @tab stable
-@item dv @tab testing @tab testing @tab n/a
-@item exit @tab testing @tab n/a @tab n/a
-@item fragmentation @tab stable @tab n/a @tab stable
-@item fs @tab stable @tab stable @tab stable
-@item gns @tab stable @tab stable @tab stable
-@item hello @tab n/a @tab n/a @tab testing
-@item hostlist @tab stable @tab stable @tab n/a
-@item identity @tab stable @tab stable @tab n/a
-@item multicast @tab experimental @tab experimental @tab experimental
-@item mysql @tab stable @tab n/a @tab stable
-@item namestore @tab n/a @tab stable @tab stable
-@item nat @tab n/a @tab n/a @tab stable
-@item nse @tab stable @tab stable @tab stable
-@item peerinfo @tab n/a @tab stable @tab stable
-@item psyc @tab experimental @tab experimental @tab experimental
-@item pt @tab n/a @tab n/a @tab n/a
-@item regex @tab stable @tab stable @tab stable
-@item revocation @tab stable @tab stable @tab stable
-@item social @tab experimental @tab experimental @tab experimental
-@item statistics @tab n/a @tab stable @tab stable
-@item testbed @tab n/a @tab testing @tab testing
-@item testing @tab n/a @tab n/a @tab testing
-@item topology @tab n/a @tab n/a @tab n/a
-@item transport @tab stable @tab stable @tab stable
-@item tun @tab n/a @tab n/a @tab stable
-@item vpn @tab testing @tab n/a @tab n/a
-@end multitable
-
-Here is a rough explanation of the values:
-
-@table @samp
-@item stable
-No incompatible changes are planned at this time; for IPC/APIs, if
-there are incompatible changes, they will be minor and might only require
-minimal changes to existing code; for P2P, changes will be avoided if at
-all possible for the 0.10.x-series
-
-@item testing
-No incompatible changes are
-planned at this time, but the code is still known to be in flux; so while
-we have no concrete plans, our expectation is that there will still be
-minor modifications; for P2P, changes will likely be extensions that
-should not break existing code
-
-@item unstable
-Changes are planned and will happen; however, they
-will not be totally radical and the result should still resemble what is
-there now; nevertheless, anticipated changes will break protocol/API
-compatibility
-
-@item experimental
-Changes are planned and the result may look nothing like
-what the API/protocol looks like today
-
-@item unknown
-Someone should think about where this subsystem headed
-
-@item n/a
-This subsystem does not have an API/IPC-protocol/P2P-protocol
-@end table
-
-@c ***********************************************************************
-@node Naming conventions and coding style guide
-@section Naming conventions and coding style guide
-
-Here you can find some rules to help you write code for GNUnet.
-
-
-
-@c ***********************************************************************
-@menu
-* Naming conventions::
-* Coding style::
-@end menu
-
-@node Naming conventions
-@subsection Naming conventions
-
-
-@c ***********************************************************************
-@menu
-* include files::
-* binaries::
-* logging::
-* configuration::
-* exported symbols::
-* private (library-internal) symbols (including structs and macros)::
-* testcases::
-* performance tests::
-* src/ directories::
-@end menu
-
-@node include files
-@subsubsection include files
-
-@itemize @bullet
-@item _lib: library without need for a process
-@item _service: library that needs a service process
-@item _plugin: plugin definition
-@item _protocol: structs used in network protocol
-@item exceptions:
-@itemize @bullet
-@item gnunet_config.h --- generated
-@item platform.h --- first included
-@item plibc.h --- external library
-@item gnunet_common.h --- fundamental routines
-@item gnunet_directories.h --- generated
-@item gettext.h --- external library
-@end itemize
-@end itemize
-
-@c ***********************************************************************
-@node binaries
-@subsubsection binaries
-
-@itemize @bullet
-@item gnunet-service-xxx: service process (has listen socket)
-@item gnunet-daemon-xxx: daemon process (no listen socket)
-@item gnunet-helper-xxx[-yyy]: SUID helper for module xxx
-@item gnunet-yyy: command-line tool for end-users
-@item libgnunet_plugin_xxx_yyy.so: plugin for API xxx
-@item libgnunetxxx.so: library for API xxx
-@end itemize
-
-@c ***********************************************************************
-@node logging
-@subsubsection logging
-
-@itemize @bullet
-@item services and daemons use their directory name in GNUNET_log_setup
-(i.e. 'core') and log using plain 'GNUNET_log'.
-@item command-line tools use their full name in GNUNET_log_setup (i.e.
-'gnunet-publish') and log using plain 'GNUNET_log'.
-@item service access libraries log using 'GNUNET_log_from' and use
-'DIRNAME-api' for the component (i.e. 'core-api')
-@item pure libraries (without associated service) use 'GNUNET_log_from'
-with the component set to their library name (without lib or '.so'),
-which should also be their directory name (i.e. 'nat')
-@item plugins should use 'GNUNET_log_from' with the directory name and the
-plugin name combined to produce the component name (i.e. 'transport-tcp').
-@item logging should be unified per-file by defining a LOG macro with the
-appropriate arguments, along these lines:@ #define LOG(kind,...)
-GNUNET_log_from (kind, "example-api",__VA_ARGS__)
-@end itemize
-
-@c ***********************************************************************
-@node configuration
-@subsubsection configuration
-
-@itemize @bullet
-@item paths (that are substituted in all filenames) are in PATHS (have as
-few as possible)
-@item all options for a particular module (src/MODULE) are under [MODULE]
-@item options for a plugin of a module are under [MODULE-PLUGINNAME]
-@end itemize
-
-@c ***********************************************************************
-@node exported symbols
-@subsubsection exported symbols
-
-@itemize @bullet
-@item must start with "GNUNET_modulename_" and be defined in
-"modulename.c"
-@item exceptions: those defined in gnunet_common.h
-@end itemize
-
-@c ***********************************************************************
-@node private (library-internal) symbols (including structs and macros)
-@subsubsection private (library-internal) symbols (including structs and macros)
-
-@itemize @bullet
-@item must NOT start with any prefix
-@item must not be exported in a way that linkers could use them or@ other
-libraries might see them via headers; they must be either@
-declared/defined in C source files or in headers that are in@ the
-respective directory under src/modulename/ and NEVER be@ declared
-in src/include/.
-@end itemize
-
-@node testcases
-@subsubsection testcases
-
-@itemize @bullet
-@item must be called "test_module-under-test_case-description.c"
-@item "case-description" maybe omitted if there is only one test
-@end itemize
-
-@c ***********************************************************************
-@node performance tests
-@subsubsection performance tests
-
-@itemize @bullet
-@item must be called "perf_module-under-test_case-description.c"
-@item "case-description" maybe omitted if there is only one performance
-test
-@item Must only be run if HAVE_BENCHMARKS is satisfied
-@end itemize
-
-@c ***********************************************************************
-@node src/ directories
-@subsubsection src/ directories
-
-@itemize @bullet
-@item gnunet-NAME: end-user applications (i.e., gnunet-search, gnunet-arm)
-@item gnunet-service-NAME: service processes with accessor library (i.e.,
-gnunet-service-arm)
-@item libgnunetNAME: accessor library (_service.h-header) or standalone
-library (_lib.h-header)
-@item gnunet-daemon-NAME: daemon process without accessor library (i.e.,
-gnunet-daemon-hostlist) and no GNUnet management port
-@item libgnunet_plugin_DIR_NAME: loadable plugins (i.e.,
-libgnunet_plugin_transport_tcp)
-@end itemize
-
-@c ***********************************************************************
-@node Coding style
-@subsection Coding style
-
-@itemize @bullet
-@item GNU guidelines generally apply
-@item Indentation is done with spaces, two per level, no tabs
-@item C99 struct initialization is fine
-@item declare only one variable per line, so@
-
-@example
-int i; int j;
-@end example
-
-instead of
-
-@example
-int i,j;
-@end example
-
-This helps keep diffs small and forces developers to think precisely about
-the type of every variable. Note that @code{char *} is different from
-@code{const char*} and @code{int} is different from @code{unsigned int}
-or @code{uint32_t}. Each variable type should be chosen with care.
-
-@item While @code{goto} should generally be avoided, having a @code{goto}
-to the end of a function to a block of clean up statements (free, close,
-etc.) can be acceptable.
-
-@item Conditions should be written with constants on the left (to avoid
-accidental assignment) and with the 'true' target being either the
-'error' case or the significantly simpler continuation. For example:
-
-@example
-if (0 != stat ("filename," &sbuf)) @{ error(); @} else @{
- /* handle normal case here */
-@}
-@end example
-
-instead of
-
-@example
-if (stat ("filename," &sbuf) == 0) @{
- /* handle normal case here */
-@} else @{ error(); @}
-@end example
-
-If possible, the error clause should be terminated with a 'return' (or
-'goto' to some cleanup routine) and in this case, the 'else' clause
-should be omitted:
-
-@example
-if (0 != stat ("filename," &sbuf)) @{ error(); return; @}
-/* handle normal case here */
-@end example
-
-This serves to avoid deep nesting. The 'constants on the left' rule
-applies to all constants (including. @code{GNUNET_SCHEDULER_NO_TASK}),
-NULL, and enums). With the two above rules (constants on left, errors in
-'true' branch), there is only one way to write most branches correctly.
-
-@item Combined assignments and tests are allowed if they do not hinder
-code clarity. For example, one can write:
-
-@example
-if (NULL == (value = lookup_function())) @{ error(); return; @}
-@end example
-
-
-@item Use @code{break} and @code{continue} wherever possible to avoid
-deep(er) nesting. Thus, we would write:
-
-@example
-next = head; while (NULL != (pos = next)) @{ next = pos->next; if (!
-should_free (pos)) continue; GNUNET_CONTAINER_DLL_remove (head, tail, pos);
-GNUNET_free (pos); @}
-@end example
-
-
-instead of
-@example
-next = head; while (NULL != (pos = next)) @{ next =
-pos->next; if (should_free (pos)) @{
- /* unnecessary nesting! */
- GNUNET_CONTAINER_DLL_remove (head, tail, pos); GNUNET_free (pos); @} @}
-@end example
-
-
-@item We primarily use @code{for} and @code{while} loops. A @code{while}
-loop is used if the method for advancing in the loop is not a
-straightforward increment operation. In particular, we use:
-
-@example
-next = head;
-while (NULL != (pos = next))
-@{
- next = pos->next;
- if (! should_free (pos))
- continue;
- GNUNET_CONTAINER_DLL_remove (head, tail, pos);
- GNUNET_free (pos);
-@}
-@end example
-
-
-to free entries in a list (as the iteration changes the structure of the
-list due to the free; the equivalent @code{for} loop does no longer
-follow the simple @code{for} paradigm of @code{for(INIT;TEST;INC)}).
-However, for loops that do follow the simple @code{for} paradigm we do
-use @code{for}, even if it involves linked lists:
-
-@example
-/* simple iteration over a linked list */
-for (pos = head; NULL != pos; pos = pos->next)
-@{
- use (pos);
-@}
-@end example
-
-
-@item The first argument to all higher-order functions in GNUnet must be
-declared to be of type @code{void *} and is reserved for a closure. We do
-not use inner functions, as trampolines would conflict with setups that
-use non-executable stacks.@ The first statement in a higher-order
-function, which unusually should be part of the variable declarations,
-should assign the @code{cls} argument to the precise expected type.
-For example:
-
-@example
-int callback (void *cls, char *args) @{
- struct Foo *foo = cls; int other_variables;
-
- /* rest of function */
-@}
-@end example
-
-
-@item It is good practice to write complex @code{if} expressions instead
-of using deeply nested @code{if} statements. However, except for addition
-and multiplication, all operators should use parens. This is fine:
-
-@example
-if ( (1 == foo) || ((0 == bar) && (x != y)) )
- return x;
-@end example
-
-
-However, this is not:
-@example
-if (1 == foo)
- return x;
-if (0 == bar && x != y)
- return x;
-@end example
-
-
-Note that splitting the @code{if} statement above is debateable as the
-@code{return x} is a very trivial statement. However, once the logic after
-the branch becomes more complicated (and is still identical), the "or"
-formulation should be used for sure.
-
-@item There should be two empty lines between the end of the function and
-the comments describing the following function. There should be a single
-empty line after the initial variable declarations of a function. If a
-function has no local variables, there should be no initial empty line. If
-a long function consists of several complex steps, those steps might be
-separated by an empty line (possibly followed by a comment describing the
-following step). The code should not contain empty lines in arbitrary
-places; if in doubt, it is likely better to NOT have an empty line (this
-way, more code will fit on the screen).
-@end itemize
-
-@c ***********************************************************************
-@node Build-system
-@section Build-system
-
-If you have code that is likely not to compile or build rules you might
-want to not trigger for most developers, use "if HAVE_EXPERIMENTAL" in
-your Makefile.am. Then it is OK to (temporarily) add non-compiling (or
-known-to-not-port) code.
-
-If you want to compile all testcases but NOT run them, run configure with
-the @code{--enable-test-suppression} option.
-
-If you want to run all testcases, including those that take a while, run
-configure with the @code{--enable-expensive-testcases} option.
-
-If you want to compile and run benchmarks, run configure with the
-@code{--enable-benchmarks} option.
-
-If you want to obtain code coverage results, run configure with the
-@code{--enable-coverage} option and run the coverage.sh script in
-@file{contrib/}.
-
-@c ***********************************************************************
-@node Developing extensions for GNUnet using the gnunet-ext template
-@section Developing extensions for GNUnet using the gnunet-ext template
-
-
-For developers who want to write extensions for GNUnet we provide the
-gnunet-ext template to provide an easy to use skeleton.
-
-gnunet-ext contains the build environment and template files for the
-development of GNUnet services, command line tools, APIs and tests.
-
-First of all you have to obtain gnunet-ext from git:
-
-@code{git clone https://gnunet.org/git/gnunet-ext.git}
-
-The next step is to bootstrap and configure it. For configure you have to
-provide the path containing GNUnet with
-@code{--with-gnunet=/path/to/gnunet} and the prefix where you want the
-install the extension using @code{--prefix=/path/to/install}:
-
-@example
-./bootstrap
-./configure --prefix=/path/to/install --with-gnunet=/path/to/gnunet
-@end example
-
-When your GNUnet installation is not included in the default linker search
-path, you have to add @code{/path/to/gnunet} to the file
-@file{/etc/ld.so.conf} and run @code{ldconfig} or your add it to the
-environmental variable @code{LD_LIBRARY_PATH} by using
-
-@code{export LD_LIBRARY_PATH=/path/to/gnunet/lib}
-
-@c ***********************************************************************
-@node Writing testcases
-@section Writing testcases
-
-Ideally, any non-trivial GNUnet code should be covered by automated
-testcases. Testcases should reside in the same place as the code that is
-being tested. The name of source files implementing tests should begin
-with "test_" followed by the name of the file that contains the code that
-is being tested.
-
-Testcases in GNUnet should be integrated with the autotools build system.
-This way, developers and anyone building binary packages will be able to
-run all testcases simply by running @code{make check}. The final
-testcases shipped with the distribution should output at most some brief
-progress information and not display debug messages by default. The
-success or failure of a testcase must be indicated by returning zero
-(success) or non-zero (failure) from the main method of the testcase. The
-integration with the autotools is relatively straightforward and only
-requires modifications to the @code{Makefile.am} in the directory
-containing the testcase. For a testcase testing the code in @code{foo.c}
-the @code{Makefile.am} would contain the following lines:
-
-@example
-check_PROGRAMS = test_foo TESTS = $(check_PROGRAMS) test_foo_SOURCES =
-test_foo.c test_foo_LDADD = $(top_builddir)/src/util/libgnunetutil.la
-@end example
-
-Naturally, other libraries used by the testcase may be specified in the
-@code{LDADD} directive as necessary.
-
-Often testcases depend on additional input files, such as a configuration
-file. These support files have to be listed using the EXTRA_DIST
-directive in order to ensure that they are included in the distribution.
-Example:
-
-@example
-EXTRA_DIST = test_foo_data.conf
-@end example
-
-Executing @code{make check} will run all testcases in the current
-directory and all subdirectories. Testcases can be compiled individually
-by running @code{make test_foo} and then invoked directly using
-@code{./test_foo}. Note that due to the use of plugins in GNUnet, it is
-typically necessary to run @code{make install} before running any
-testcases. Thus the canonical command @code{make check install} has to be
-changed to @code{make install check} for GNUnet.
-
-@c ***********************************************************************
-@node GNUnet's TESTING library
-@section GNUnet's TESTING library
-
-The TESTING library is used for writing testcases which involve starting a
-single or multiple peers. While peers can also be started by testcases
-using the ARM subsystem, using TESTING library provides an elegant way to
-do this. The configurations of the peers are auto-generated from a given
-template to have non-conflicting port numbers ensuring that peers'
-services do not run into bind errors. This is achieved by testing ports'
-availability by binding a listening socket to them before allocating them
-to services in the generated configurations.
-
-An another advantage while using TESTING is that it shortens the testcase
-startup time as the hostkeys for peers are copied from a pre-computed set
-of hostkeys instead of generating them at peer startup which may take a
-considerable amount of time when starting multiple peers or on an embedded
-processor.
-
-TESTING also allows for certain services to be shared among peers. This
-feature is invaluable when testing with multiple peers as it helps to
-reduce the number of services run per each peer and hence the total
-number of processes run per testcase.
-
-TESTING library only handles creating, starting and stopping peers.
-Features useful for testcases such as connecting peers in a topology are
-not available in TESTING but are available in the TESTBED subsystem.
-Furthermore, TESTING only creates peers on the localhost, however by
-using TESTBED testcases can benefit from creating peers across multiple
-hosts.
-
-@menu
-* API::
-* Finer control over peer stop::
-* Helper functions::
-* Testing with multiple processes::
-@end menu
-
-@c ***********************************************************************
-@node API
-@subsection API
-
-TESTING abstracts a group of peers as a TESTING system. All peers in a
-system have common hostname and no two services of these peers have a
-same port or a UNIX domain socket path.
-
-TESTING system can be created with the function
-@code{GNUNET_TESTING_system_create()} which returns a handle to the
-system. This function takes a directory path which is used for generating
-the configurations of peers, an IP address from which connections to the
-peers' services should be allowed, the hostname to be used in peers'
-configuration, and an array of shared service specifications of type
-@code{struct GNUNET_TESTING_SharedService}.
-
-The shared service specification must specify the name of the service to
-share, the configuration pertaining to that shared service and the
-maximum number of peers that are allowed to share a single instance of
-the shared service.
-
-TESTING system created with @code{GNUNET_TESTING_system_create()} chooses
-ports from the default range 12000 - 56000 while auto-generating
-configurations for peers. This range can be customised with the function
-@code{GNUNET_TESTING_system_create_with_portrange()}. This function is
-similar to @code{GNUNET_TESTING_system_create()} except that it take 2
-additional parameters --- the start and end of the port range to use.
-
-A TESTING system is destroyed with the funciton
-@code{GNUNET_TESTING_system_destory()}. This function takes the handle of
-the system and a flag to remove the files created in the directory used
-to generate configurations.
-
-A peer is created with the function
-@code{GNUNET_TESTING_peer_configure()}. This functions takes the system
-handle, a configuration template from which the configuration for the peer
-is auto-generated and the index from where the hostkey for the peer has to
-be copied from. When successfull, this function returs a handle to the
-peer which can be used to start and stop it and to obtain the identity of
-the peer. If unsuccessful, a NULL pointer is returned with an error
-message. This function handles the generated configuration to have
-non-conflicting ports and paths.
-
-Peers can be started and stopped by calling the functions
-@code{GNUNET_TESTING_peer_start()} and @code{GNUNET_TESTING_peer_stop()}
-respectively. A peer can be destroyed by calling the function
-@code{GNUNET_TESTING_peer_destroy}. When a peer is destroyed, the ports
-and paths in allocated in its configuration are reclaimed for usage in new
-peers.
-
-@c ***********************************************************************
-@node Finer control over peer stop
-@subsection Finer control over peer stop
-
-Using @code{GNUNET_TESTING_peer_stop()} is normally fine for testcases.
-However, calling this function for each peer is inefficient when trying to
-shutdown multiple peers as this function sends the termination signal to
-the given peer process and waits for it to terminate. It would be faster
-in this case to send the termination signals to the peers first and then
-wait on them. This is accomplished by the functions
-@code{GNUNET_TESTING_peer_kill()} which sends a termination signal to the
-peer, and the function @code{GNUNET_TESTING_peer_wait()} which waits on
-the peer.
-
-Further finer control can be achieved by choosing to stop a peer
-asynchronously with the function @code{GNUNET_TESTING_peer_stop_async()}.
-This function takes a callback parameter and a closure for it in addition
-to the handle to the peer to stop. The callback function is called with
-the given closure when the peer is stopped. Using this function
-eliminates blocking while waiting for the peer to terminate.
-
-An asynchronous peer stop can be cancelled by calling the function
-@code{GNUNET_TESTING_peer_stop_async_cancel()}. Note that calling this
-function does not prevent the peer from terminating if the termination
-signal has already been sent to it. It does, however, cancels the
-callback to be called when the peer is stopped.
-
-@c ***********************************************************************
-@node Helper functions
-@subsection Helper functions
-
-Most of the testcases can benefit from an abstraction which configures a
-peer and starts it. This is provided by the function
-@code{GNUNET_TESTING_peer_run()}. This function takes the testing
-directory pathname, a configuration template, a callback and its closure.
-This function creates a peer in the given testing directory by using the
-configuration template, starts the peer and calls the given callback with
-the given closure.
-
-The function @code{GNUNET_TESTING_peer_run()} starts the ARM service of
-the peer which starts the rest of the configured services. A similar
-function @code{GNUNET_TESTING_service_run} can be used to just start a
-single service of a peer. In this case, the peer's ARM service is not
-started; instead, only the given service is run.
-
-@c ***********************************************************************
-@node Testing with multiple processes
-@subsection Testing with multiple processes
-
-When testing GNUnet, the splitting of the code into a services and clients
-often complicates testing. The solution to this is to have the testcase
-fork @code{gnunet-service-arm}, ask it to start the required server and
-daemon processes and then execute appropriate client actions (to test the
-client APIs or the core module or both). If necessary, multiple ARM
-services can be forked using different ports (!) to simulate a network.
-However, most of the time only one ARM process is needed. Note that on
-exit, the testcase should shutdown ARM with a @code{TERM} signal (to give
-it the chance to cleanly stop its child processes).
-
-The following code illustrates spawning and killing an ARM process from a
-testcase:
-
-@example
-static void run (void *cls, char *const *args, const char
-*cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg) @{ struct
-GNUNET_OS_Process *arm_pid; arm_pid = GNUNET_OS_start_process (NULL, NULL,
-"gnunet-service-arm", "gnunet-service-arm", "-c", cfgname, NULL);
- /* do real test work here */
- if (0 != GNUNET_OS_process_kill (arm_pid, SIGTERM)) GNUNET_log_strerror
- (GNUNET_ERROR_TYPE_WARNING, "kill"); GNUNET_assert (GNUNET_OK ==
- GNUNET_OS_process_wait (arm_pid)); GNUNET_OS_process_close (arm_pid); @}
-
-GNUNET_PROGRAM_run (argc, argv, "NAME-OF-TEST", "nohelp", options, &run, cls);
-@end example
-
-
-An alternative way that works well to test plugins is to implement a
-mock-version of the environment that the plugin expects and then to
-simply load the plugin directly.
-
-@c ***********************************************************************
-@node Performance regression analysis with Gauger
-@section Performance regression analysis with Gauger
-
-To help avoid performance regressions, GNUnet uses Gauger. Gauger is a
-simple logging tool that allows remote hosts to send performance data to
-a central server, where this data can be analyzed and visualized. Gauger
-shows graphs of the repository revisions and the performace data recorded
-for each revision, so sudden performance peaks or drops can be identified
-and linked to a specific revision number.
-
-In the case of GNUnet, the buildbots log the performance data obtained
-during the tests after each build. The data can be accesed on GNUnet's
-Gauger page.
-
-The menu on the left allows to select either the results of just one
-build bot (under "Hosts") or review the data from all hosts for a given
-test result (under "Metrics"). In case of very different absolute value
-of the results, for instance arm vs. amd64 machines, the option
-"Normalize" on a metric view can help to get an idea about the
-performance evolution across all hosts.
-
-Using Gauger in GNUnet and having the performance of a module tracked over
-time is very easy. First of course, the testcase must generate some
-consistent metric, which makes sense to have logged. Highly volatile or
-random dependant metrics probably are not ideal candidates for meaningful
-regression detection.
-
-To start logging any value, just include @code{gauger.h} in your testcase
-code. Then, use the macro @code{GAUGER()} to make the buildbots log
-whatever value is of interest for you to @code{gnunet.org}'s Gauger
-server. No setup is necessary as most buildbots have already everything
-in place and new metrics are created on demand. To delete a metric, you
-need to contact a member of the GNUnet development team (a file will need
-to be removed manually from the respective directory).
-
-The code in the test should look like this:
-
-@example
-[other includes]
-#include <gauger.h>
-
-int main (int argc, char *argv[]) @{
-
- [run test, generate data] GAUGER("YOUR_MODULE", "METRIC_NAME", (float)value,
- "UNIT"); @}
-@end example
-
-
-Where:
-
-@table @asis
-
-@item @strong{YOUR_MODULE} is a category in the gauger page and should be
-the name of the module or subsystem like "Core" or "DHT"
-@item @strong{METRIC} is
-the name of the metric being collected and should be concise and
-descriptive, like "PUT operations in sqlite-datastore".
-@item @strong{value} is the value
-of the metric that is logged for this run.
-@item @strong{UNIT} is the unit in
-which the value is measured, for instance "kb/s" or "kb of RAM/node".
-@end table
-
-If you wish to use Gauger for your own project, you can grab a copy of the
-latest stable release or check out Gauger's Subversion repository.
-
-@c ***********************************************************************
-@node GNUnet's TESTBED Subsystem
-@section GNUnet's TESTBED Subsystem
-
-The TESTBED subsystem facilitates testing and measuring of multi-peer
-deployments on a single host or over multiple hosts.
-
-The architecture of the testbed module is divided into the following:
-@itemize @bullet
-
-@item Testbed API: An API which is used by the testing driver programs. It
-provides with functions for creating, destroying, starting, stopping
-peers, etc.
-
-@item Testbed service (controller): A service which is started through the
-Testbed API. This service handles operations to create, destroy, start,
-stop peers, connect them, modify their configurations.
-
-@item Testbed helper: When a controller has to be started on a host, the
-testbed API starts the testbed helper on that host which in turn starts
-the controller. The testbed helper receives a configuration for the
-controller through its stdin and changes it to ensure the controller
-doesn't run into any port conflict on that host.
-@end itemize
-
-
-The testbed service (controller) is different from the other GNUnet
-services in that it is not started by ARM and is not supposed to be run
-as a daemon. It is started by the testbed API through a testbed helper.
-In a typical scenario involving multiple hosts, a controller is started
-on each host. Controllers take up the actual task of creating peers,
-starting and stopping them on the hosts they run.
-
-While running deployments on a single localhost the testbed API starts the
-testbed helper directly as a child process. When running deployments on
-remote hosts the testbed API starts Testbed Helpers on each remote host
-through remote shell. By default testbed API uses SSH as a remote shell.
-This can be changed by setting the environmental variable
-GNUNET_TESTBED_RSH_CMD to the required remote shell program. This
-variable can also contain parameters which are to be passed to the remote
-shell program. For e.g:
-
-@example
-export GNUNET_TESTBED_RSH_CMD="ssh -o BatchMode=yes \
--o NoHostAuthenticationForLocalhost=yes %h"@
-@end example
-
-Substitutions are allowed int the above command string also allows for
-substitions. through placemarks which begin with a `%'. At present the
-following substitutions are supported
-
-@itemize @bullet
-@item
-%h: hostname
-@item
-%u: username
-@item
-%p: port
-@end itemize
-
-Note that the substitution placemark is replaced only when the
-corresponding field is available and only once. Specifying @code{%u@@%h}
-doesn't work either. If you want to user username substitutions for SSH
-use the argument @code{-l} before the username substitution.
-Ex: @code{ssh -l %u -p %p %h}
-
-The testbed API and the helper communicate through the helpers stdin and
-stdout. As the helper is started through a remote shell on remote hosts
-any output messages from the remote shell interfere with the communication
-and results in a failure while starting the helper. For this reason, it is
-suggested to use flags to make the remote shells produce no output
-messages and to have password-less logins. The default remote shell, SSH,
-the default options are:
-
-@example
--o BatchMode=yes -o NoHostBasedAuthenticationForLocalhost=yes"
-@end example
-
-Password-less logins should be ensured by using SSH keys.
-
-Since the testbed API executes the remote shell as a non-interactive
-shell, certain scripts like .bashrc, .profiler may not be executed. If
-this is the case testbed API can be forced to execute an interactive
-shell by setting up the environmental variable
-`GNUNET_TESTBED_RSH_CMD_SUFFIX' to a shell program.
-An example could be:
-
-@example
-export GNUNET_TESTBED_RSH_CMD_SUFFIX="sh -lc"
-@end example
-
-The testbed API will then execute the remote shell program as:
-
-@example
-$GNUNET_TESTBED_RSH_CMD -p $port $dest $GNUNET_TESTBED_RSH_CMD_SUFFIX \
-gnunet-helper-testbed
-@end example
-
-On some systems, problems may arise while starting testbed helpers if
-GNUnet is installed into a custom location since the helper may not be
-found in the standard path. This can be addressed by setting the variable
-`HELPER_BINARY_PATH' to the path of the testbed helper. Testbed API will
-then use this path to start helper binaries both locally and remotely.
-
-Testbed API can accessed by including "gnunet_testbed_service.h" file and
-linking with -lgnunettestbed.
-
-
-
-@c ***********************************************************************
-@menu
-* Supported Topologies::
-* Hosts file format::
-* Topology file format::
-* Testbed Barriers::
-* Automatic large-scale deployment of GNUnet in the PlanetLab testbed::
-* TESTBED Caveats::
-@end menu
-
-@node Supported Topologies
-@subsection Supported Topologies
-
-While testing multi-peer deployments, it is often needed that the peers
-are connected in some topology. This requirement is addressed by the
-function @code{GNUNET_TESTBED_overlay_connect()} which connects any given
-two peers in the testbed.
-
-The API also provides a helper function
-@code{GNUNET_TESTBED_overlay_configure_topology()} to connect a given set
-of peers in any of the following supported topologies:
-
-@itemize @bullet
-
-@item @code{GNUNET_TESTBED_TOPOLOGY_CLIQUE}: All peers are connected with
-each other
-
-@item @code{GNUNET_TESTBED_TOPOLOGY_LINE}: Peers are connected to form a
-line
-
-@item @code{GNUNET_TESTBED_TOPOLOGY_RING}: Peers are connected to form a
-ring topology
-
-@item @code{GNUNET_TESTBED_TOPOLOGY_2D_TORUS}: Peers are connected to
-form a 2 dimensional torus topology. The number of peers may not be a
-perfect square, in that case the resulting torus may not have the uniform
-poloidal and toroidal lengths
-
-@item @code{GNUNET_TESTBED_TOPOLOGY_ERDOS_RENYI}: Topology is generated
-to form a random graph. The number of links to be present should be given
-
-@item @code{GNUNET_TESTBED_TOPOLOGY_SMALL_WORLD}: Peers are connected to
-form a 2D Torus with some random links among them. The number of random
-links are to be given
-
-@item @code{GNUNET_TESTBED_TOPOLOGY_SMALL_WORLD_RING}: Peers are
-connected to form a ring with some random links among them. The number of
-random links are to be given
-
-@item @code{GNUNET_TESTBED_TOPOLOGY_SCALE_FREE}: Connects peers in a
-topology where peer connectivity follows power law - new peers are
-connected with high probabililty to well connected peers.
-@footnote{See Emergence of Scaling in Random Networks. Science 286,
-509-512, 1999.}
-
-@item @code{GNUNET_TESTBED_TOPOLOGY_FROM_FILE}: The topology information
-is loaded from a file. The path to the file has to be given. See Topology
-file format for the format of this file.
-
-@item @code{GNUNET_TESTBED_TOPOLOGY_NONE}: No topology
-@end itemize
-
-
-The above supported topologies can be specified respectively by setting
-the variable @code{OVERLAY_TOPOLOGY} to the following values in the
-configuration passed to Testbed API functions
-@code{GNUNET_TESTBED_test_run()} and
-@code{GNUNET_TESTBED_run()}:
-@itemize @bullet
-@item @code{CLIQUE}
-@item @code{RING}
-@item @code{LINE}
-@item @code{2D_TORUS}
-@item @code{RANDOM}
-@item @code{SMALL_WORLD}
-@item @code{SMALL_WORLD_RING}
-@item @code{SCALE_FREE}
-@item @code{FROM_FILE}
-@item @code{NONE}
-@end itemize
-
-
-Topologies @code{RANDOM}, @code{SMALL_WORLD} and @code{SMALL_WORLD_RING}
-require the option @code{OVERLAY_RANDOM_LINKS} to be set to the number of
-random links to be generated in the configuration. The option will be
-ignored for the rest of the topologies.
-
-Topology @code{SCALE_FREE} requires the options
-@code{SCALE_FREE_TOPOLOGY_CAP} to be set to the maximum number of peers
-which can connect to a peer and @code{SCALE_FREE_TOPOLOGY_M} to be set to
-how many peers a peer should be atleast connected to.
-
-Similarly, the topology @code{FROM_FILE} requires the option
-@code{OVERLAY_TOPOLOGY_FILE} to contain the path of the file containing
-the topology information. This option is ignored for the rest of the
-topologies. See Topology file format for the format of this file.
-
-@c ***********************************************************************
-@node Hosts file format
-@subsection Hosts file format
-
-The testbed API offers the function GNUNET_TESTBED_hosts_load_from_file()
-to load from a given file details about the hosts which testbed can use
-for deploying peers. This function is useful to keep the data about hosts
-separate instead of hard coding them in code.
-
-Another helper function from testbed API, GNUNET_TESTBED_run() also takes
-a hosts file name as its parameter. It uses the above function to
-populate the hosts data structures and start controllers to deploy peers.
-
-These functions require the hosts file to be of the following format:
-@itemize @bullet
-@item Each line is interpreted to have details about a host
-@item Host details should include the username to use for logging into the
-host, the hostname of the host and the port number to use for the remote
-shell program. All thee values should be given.
-@item These details should be given in the following format:
-@code{<username>@@<hostname>:<port>}
-@end itemize
-
-Note that having canonical hostnames may cause problems while resolving
-the IP addresses (See this bug). Hence it is advised to provide the hosts'
-IP numerical addresses as hostnames whenever possible.
-
-@c ***********************************************************************
-@node Topology file format
-@subsection Topology file format
-
-A topology file describes how peers are to be connected. It should adhere
-to the following format for testbed to parse it correctly.
-
-Each line should begin with the target peer id. This should be followed by
-a colon(`:') and origin peer ids seperated by `|'. All spaces except for
-newline characters are ignored. The API will then try to connect each
-origin peer to the target peer.
-
-For example, the following file will result in 5 overlay connections:
-[2->1], [3->1],[4->3], [0->3], [2->0]@ @code{@ 1:2|3@ 3:4| 0@ 0: 2@ }
-
-@c ***********************************************************************
-@node Testbed Barriers
-@subsection Testbed Barriers
-
-The testbed subsystem's barriers API facilitates coordination among the
-peers run by the testbed and the experiment driver. The concept is
-similar to the barrier synchronisation mechanism found in parallel
-programming or multi-threading paradigms - a peer waits at a barrier upon
-reaching it until the barrier is reached by a predefined number of peers.
-This predefined number of peers required to cross a barrier is also called
-quorum. We say a peer has reached a barrier if the peer is waiting for the
-barrier to be crossed. Similarly a barrier is said to be reached if the
-required quorum of peers reach the barrier. A barrier which is reached is
-deemed as crossed after all the peers waiting on it are notified.
-
-The barriers API provides the following functions:
-@itemize @bullet
-@item @strong{@code{GNUNET_TESTBED_barrier_init()}:} function to
-initialse a barrier in the experiment
-@item @strong{@code{GNUNET_TESTBED_barrier_cancel()}:} function to cancel
-a barrier which has been initialised before
-@item @strong{@code{GNUNET_TESTBED_barrier_wait()}:} function to signal
-barrier service that the caller has reached a barrier and is waiting for
-it to be crossed
-@item @strong{@code{GNUNET_TESTBED_barrier_wait_cancel()}:} function to
-stop waiting for a barrier to be crossed
-@end itemize
-
-
-Among the above functions, the first two, namely
-@code{GNUNET_TESTBED_barrier_init()} and
-@code{GNUNET_TESTBED_barrier_cancel()} are used by experiment drivers. All
-barriers should be initialised by the experiment driver by calling
-@code{GNUNET_TESTBED_barrier_init()}. This function takes a name to
-identify the barrier, the quorum required for the barrier to be crossed
-and a notification callback for notifying the experiment driver when the
-barrier is crossed. @code{GNUNET_TESTBED_barrier_cancel()} cancels an
-initialised barrier and frees the resources allocated for it. This
-function can be called upon a initialised barrier before it is crossed.
-
-The remaining two functions @code{GNUNET_TESTBED_barrier_wait()} and
-@code{GNUNET_TESTBED_barrier_wait_cancel()} are used in the peer's
-processes. @code{GNUNET_TESTBED_barrier_wait()} connects to the local
-barrier service running on the same host the peer is running on and
-registers that the caller has reached the barrier and is waiting for the
-barrier to be crossed. Note that this function can only be used by peers
-which are started by testbed as this function tries to access the local
-barrier service which is part of the testbed controller service. Calling
-@code{GNUNET_TESTBED_barrier_wait()} on an uninitialised barrier results
-in failure. @code{GNUNET_TESTBED_barrier_wait_cancel()} cancels the
-notification registered by @code{GNUNET_TESTBED_barrier_wait()}.
-
-
-@c ***********************************************************************
-@menu
-* Implementation::
-@end menu
-
-@node Implementation
-@subsubsection Implementation
-
-Since barriers involve coordination between experiment driver and peers,
-the barrier service in the testbed controller is split into two
-components. The first component responds to the message generated by the
-barrier API used by the experiment driver (functions
-@code{GNUNET_TESTBED_barrier_init()} and
-@code{GNUNET_TESTBED_barrier_cancel()}) and the second component to the
-messages generated by barrier API used by peers (functions
-@code{GNUNET_TESTBED_barrier_wait()} and
-@code{GNUNET_TESTBED_barrier_wait_cancel()}).
-
-Calling @code{GNUNET_TESTBED_barrier_init()} sends a
-@code{GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_INIT} message to the master
-controller. The master controller then registers a barrier and calls
-@code{GNUNET_TESTBED_barrier_init()} for each its subcontrollers. In this
-way barrier initialisation is propagated to the controller hierarchy.
-While propagating initialisation, any errors at a subcontroller such as
-timeout during further propagation are reported up the hierarchy back to
-the experiment driver.
-
-Similar to @code{GNUNET_TESTBED_barrier_init()},
-@code{GNUNET_TESTBED_barrier_cancel()} propagates
-@code{GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_CANCEL} message which causes
-controllers to remove an initialised barrier.
-
-The second component is implemented as a separate service in the binary
-`gnunet-service-testbed' which already has the testbed controller service.
-Although this deviates from the gnunet process architecture of having one
-service per binary, it is needed in this case as this component needs
-access to barrier data created by the first component. This component
-responds to @code{GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_WAIT} messages from
-local peers when they call @code{GNUNET_TESTBED_barrier_wait()}. Upon
-receiving @code{GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_WAIT} message, the
-service checks if the requested barrier has been initialised before and
-if it was not initialised, an error status is sent through
-@code{GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS} message to the local
-peer and the connection from the peer is terminated. If the barrier is
-initialised before, the barrier's counter for reached peers is incremented
-and a notification is registered to notify the peer when the barrier is
-reached. The connection from the peer is left open.
-
-When enough peers required to attain the quorum send
-@code{GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_WAIT} messages, the controller
-sends a @code{GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS} message to its
-parent informing that the barrier is crossed. If the controller has
-started further subcontrollers, it delays this message until it receives
-a similar notification from each of those subcontrollers. Finally, the
-barriers API at the experiment driver receives the
-@code{GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS} when the barrier is
-reached at all the controllers.
-
-The barriers API at the experiment driver responds to the
-@code{GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS} message by echoing it
-back to the master controller and notifying the experiment controller
-through the notification callback that a barrier has been crossed. The
-echoed @code{GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS} message is
-propagated by the master controller to the controller hierarchy. This
-propagation triggers the notifications registered by peers at each of the
-controllers in the hierarchy. Note the difference between this downward
-propagation of the @code{GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS}
-message from its upward propagation --- the upward propagation is needed
-for ensuring that the barrier is reached by all the controllers and the
-downward propagation is for triggering that the barrier is crossed.
-
-@c ***********************************************************************
-@node Automatic large-scale deployment of GNUnet in the PlanetLab testbed
-@subsection Automatic large-scale deployment of GNUnet in the PlanetLab testbed
-
-PlanetLab is as a testbed for computer networking and distributed systems
-research. It was established in 2002 and as of June 2010 was composed of
-1090 nodes at 507 sites worldwide.
-
-To automate the GNUnet we created a set of automation tools to simplify
-the large-scale deployment. We provide you a set of scripts you can use
-to deploy GNUnet on a set of nodes and manage your installation.
-
-Please also check @uref{https://gnunet.org/installation-fedora8-svn} and
-@uref{https://gnunet.org/installation-fedora12-svn} to find detailled
-instructions how to install GNUnet on a PlanetLab node.
-
-
-@c ***********************************************************************
-@menu
-* PlanetLab Automation for Fedora8 nodes::
-* Install buildslave on PlanetLab nodes running fedora core 8::
-* Setup a new PlanetLab testbed using GPLMT::
-* Why do i get an ssh error when using the regex profiler?::
-@end menu
-
-@node PlanetLab Automation for Fedora8 nodes
-@subsubsection PlanetLab Automation for Fedora8 nodes
-
-@c ***********************************************************************
-@node Install buildslave on PlanetLab nodes running fedora core 8
-@subsubsection Install buildslave on PlanetLab nodes running fedora core 8
-@c ** Actually this is a subsubsubsection, but must be fixed differently
-@c ** as subsubsection is the lowest.
-
-Since most of the PlanetLab nodes are running the very old fedora core 8
-image, installing the buildslave software is quite some pain. For our
-PlanetLab testbed we figured out how to install the buildslave software
-best.
-
-@c This is a vvery terrible way to suggest installing software.
-@c FIXME: Is there an official, safer way instead of blind-piping a
-@c script?
-@c FIXME: Use newer pypi URLs below.
-Install Distribute for python:@ @code{@ curl
-http://python-distribute.org/distribute_setup.py | sudo python@ }
-
-Install Distribute for zope.interface <= 3.8.0 (4.0 and 4.0.1 will not
-work):
-
-@example
-wget https://pypi.python.org/packages/source/z/zope.interface/zope.interface-3.8.0.tar.gz
-tar zvfz zope.interface-3.8.0.tar.gz@ cd zope.interface-3.8.0
-sudo python setup.py install
-@end example
-
-Install the buildslave software (0.8.6 was the latest version):
-
-@example
-wget http://buildbot.googlecode.com/files/buildbot-slave-0.8.6p1.tar.gz
-tar xvfz buildbot-slave-0.8.6p1.tar.gz@ cd buildslave-0.8.6p1
-sudo python setup.py install
-@end example
-
-The setup will download the matching twisted package and install it.
-It will also try to install the latest version of zope.interface which
-will fail to install. Buildslave will work anyway since version 3.8.0
-was installed before!
-
-@c ***********************************************************************
-@node Setup a new PlanetLab testbed using GPLMT
-@subsubsection Setup a new PlanetLab testbed using GPLMT
-
-@itemize @bullet
-@item Get a new slice and assign nodes
-Ask your PlanetLab PI to give you a new slice and assign the nodes you
-need
-@item Install a buildmaster
-You can stick to the buildbot documentation:@
-@uref{http://buildbot.net/buildbot/docs/current/manual/installation.html}
-@item Install the buildslave software on all nodes
-To install the buildslave on all nodes assigned to your slice you can use
-the tasklist @code{install_buildslave_fc8.xml} provided with GPLMT:
-
-@example
-./gplmt.py -c contrib/tumple_gnunet.conf -t \
-contrib/tasklists/install_buildslave_fc8.xml -a -p <planetlab password>
-@end example
-
-@item Create the buildmaster configuration and the slave setup commands
-
-The master and the and the slaves have need to have credentials and the
-master has to have all nodes configured. This can be done with the
-@code{create_buildbot_configuration.py} script in the @code{scripts}
-directory
-
-This scripts takes a list of nodes retrieved directly from PlanetLab or
-read from a file and a configuration template and creates:
-
-@itemize @bullet
-@item a tasklist which can be executed with gplmt to setup the slaves
-@item a master.cfg file containing a PlanetLab nodes
-@end itemize
-
-A configuration template is included in the <contrib>, most important is
-that the script replaces the following tags in the template:
-
-%GPLMT_BUILDER_DEFINITION :@ GPLMT_BUILDER_SUMMARY@ GPLMT_SLAVES@
-%GPLMT_SCHEDULER_BUILDERS
-
-Create configuration for all nodes assigned to a slice:@ @code{@
-./create_buildbot_configuration.py -u <planetlab username> -p <planetlab
-password> -s <slice> -m <buildmaster+port> -t <template>@ }@ Create
-configuration for some nodes in a file:@ @code{@
-./create_buildbot_configuration.p -f <node_file> -m <buildmaster+port> -t
-<template>@ }
-
-@item Copy the @code{master.cfg} to the buildmaster and start it
-Use @code{buildbot start <basedir>} to start the server
-@item Setup the buildslaves
-@end itemize
-
-@c ***********************************************************************
-@node Why do i get an ssh error when using the regex profiler?
-@subsubsection Why do i get an ssh error when using the regex profiler?
-
-Why do i get an ssh error "Permission denied (publickey,password)." when
-using the regex profiler although passwordless ssh to localhost works
-using publickey and ssh-agent?
-
-You have to generate a public/private-key pair with no password:@
-@code{ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_localhost}@
-and then add the following to your ~/.ssh/config file:
-
-@code{Host 127.0.0.1@ IdentityFile ~/.ssh/id_localhost}
-
-now make sure your hostsfile looks like@
-
-[USERNAME]@@127.0.0.1:22@
-[USERNAME]@@127.0.0.1:22
-
-You can test your setup by running `ssh 127.0.0.1` in a terminal and then
-in the opened session run it again. If you were not asked for a password
-on either login, then you should be good to go.
-
-@c ***********************************************************************
-@node TESTBED Caveats
-@subsection TESTBED Caveats
-
-This section documents a few caveats when using the GNUnet testbed
-subsystem.
-
-
-@c ***********************************************************************
-@menu
-* CORE must be started::
-* ATS must want the connections::
-@end menu
-
-@node CORE must be started
-@subsubsection CORE must be started
-
-A simple issue is #3993: Your configuration MUST somehow ensure that for
-each peer the CORE service is started when the peer is setup, otherwise
-TESTBED may fail to connect peers when the topology is initialized, as
-TESTBED will start some CORE services but not necessarily all (but it
-relies on all of them running). The easiest way is to set
-'FORCESTART = YES' in the '[core]' section of the configuration file.
-Alternatively, having any service that directly or indirectly depends on
-CORE being started with FORCESTART will also do. This issue largely arises
-if users try to over-optimize by not starting any services with
-FORCESTART.
-
-@c ***********************************************************************
-@node ATS must want the connections
-@subsubsection ATS must want the connections
-
-When TESTBED sets up connections, it only offers the respective HELLO
-information to the TRANSPORT service. It is then up to the ATS service to
-@strong{decide} to use the connection. The ATS service will typically
-eagerly establish any connection if the number of total connections is
-low (relative to bandwidth). Details may further depend on the
-specific ATS backend that was configured. If ATS decides to NOT establish
-a connection (even though TESTBED provided the required information), then
-that connection will count as failed for TESTBED. Note that you can
-configure TESTBED to tolerate a certain number of connection failures
-(see '-e' option of gnunet-testbed-profiler). This issue largely arises
-for dense overlay topologies, especially if you try to create cliques
-with more than 20 peers.
-
-@c ***********************************************************************
-@node libgnunetutil
-@section libgnunetutil
-
-libgnunetutil is the fundamental library that all GNUnet code builds upon.
-Ideally, this library should contain most of the platform dependent code
-(except for user interfaces and really special needs that only few
-applications have). It is also supposed to offer basic services that most
-if not all GNUnet binaries require. The code of libgnunetutil is in the
-@file{src/util/} directory. The public interface to the library is in the
-gnunet_util.h header. The functions provided by libgnunetutil fall
-roughly into the following categories (in roughly the order of importance
-for new developers):
-
-@itemize @bullet
-@item logging (common_logging.c)
-@item memory allocation (common_allocation.c)
-@item endianess conversion (common_endian.c)
-@item internationalization (common_gettext.c)
-@item String manipulation (string.c)
-@item file access (disk.c)
-@item buffered disk IO (bio.c)
-@item time manipulation (time.c)
-@item configuration parsing (configuration.c)
-@item command-line handling (getopt*.c)
-@item cryptography (crypto_*.c)
-@item data structures (container_*.c)
-@item CPS-style scheduling (scheduler.c)
-@item Program initialization (program.c)
-@item Networking (network.c, client.c, server*.c, service.c)
-@item message queueing (mq.c)
-@item bandwidth calculations (bandwidth.c)
-@item Other OS-related (os*.c, plugin.c, signal.c)
-@item Pseudonym management (pseudonym.c)
-@end itemize
-
-It should be noted that only developers that fully understand this entire
-API will be able to write good GNUnet code.
-
-Ideally, porting GNUnet should only require porting the gnunetutil
-library. More testcases for the gnunetutil APIs are therefore a great
-way to make porting of GNUnet easier.
-
-@menu
-* Logging::
-* Interprocess communication API (IPC)::
-* Cryptography API::
-* Message Queue API::
-* Service API::
-* Optimizing Memory Consumption of GNUnet's (Multi-) Hash Maps::
-* The CONTAINER_MDLL API::
-@end menu
-
-@c ***********************************************************************
-@node Logging
-@subsection Logging
-
-GNUnet is able to log its activity, mostly for the purposes of debugging
-the program at various levels.
-
-@file{gnunet_common.h} defines several @strong{log levels}:
-@table @asis
-
-@item ERROR for errors (really problematic situations, often leading to
-crashes)
-@item WARNING for warnings (troubling situations that might have
-negative consequences, although not fatal)
-@item INFO for various information.
-Used somewhat rarely, as GNUnet statistics is used to hold and display
-most of the information that users might find interesting.
-@item DEBUG for debugging.
-Does not produce much output on normal builds, but when extra logging is
-enabled at compile time, a staggering amount of data is outputted under
-this log level.
-@end table
-
-
-Normal builds of GNUnet (configured with @code{--enable-logging[=yes]})
-are supposed to log nothing under DEBUG level. The
-@code{--enable-logging=verbose} configure option can be used to create a
-build with all logging enabled. However, such build will produce large
-amounts of log data, which is inconvenient when one tries to hunt down a
-specific problem.
-
-To mitigate this problem, GNUnet provides facilities to apply a filter to
-reduce the logs:
-@table @asis
-
-@item Logging by default When no log levels are configured in any other
-way (see below), GNUnet will default to the WARNING log level. This
-mostly applies to GNUnet command line utilities, services and daemons;
-tests will always set log level to WARNING or, if
-@code{--enable-logging=verbose} was passed to configure, to DEBUG. The
-default level is suggested for normal operation.
-@item The -L option Most GNUnet executables accept an "-L loglevel" or
-"--log=loglevel" option. If used, it makes the process set a global log
-level to "loglevel". Thus it is possible to run some processes
-with -L DEBUG, for example, and others with -L ERROR to enable specific
-settings to diagnose problems with a particular process.
-@item Configuration files. Because GNUnet
-service and deamon processes are usually launched by gnunet-arm, it is not
-possible to pass different custom command line options directly to every
-one of them. The options passed to @code{gnunet-arm} only affect
-gnunet-arm and not the rest of GNUnet. However, one can specify a
-configuration key "OPTIONS" in the section that corresponds to a service
-or a daemon, and put a value of "-L loglevel" there. This will make the
-respective service or daemon set its log level to "loglevel" (as the
-value of OPTIONS will be passed as a command-line argument).
-
-To specify the same log level for all services without creating separate
-"OPTIONS" entries in the configuration for each one, the user can specify
-a config key "GLOBAL_POSTFIX" in the [arm] section of the configuration
-file. The value of GLOBAL_POSTFIX will be appended to all command lines
-used by the ARM service to run other services. It can contain any option
-valid for all GNUnet commands, thus in particular the "-L loglevel"
-option. The ARM service itself is, however, unaffected by GLOBAL_POSTFIX;
-to set log level for it, one has to specify "OPTIONS" key in the [arm]
-section.
-@item Environment variables.
-Setting global per-process log levels with "-L loglevel" does not offer
-sufficient log filtering granularity, as one service will call interface
-libraries and supporting libraries of other GNUnet services, potentially
-producing lots of debug log messages from these libraries. Also, changing
-the config file is not always convenient (especially when running the
-GNUnet test suite).@ To fix that, and to allow GNUnet to use different
-log filtering at runtime without re-compiling the whole source tree, the
-log calls were changed to be configurable at run time. To configure them
-one has to define environment variables "GNUNET_FORCE_LOGFILE",
-"GNUNET_LOG" and/or "GNUNET_FORCE_LOG":
-@itemize @bullet
-
-@item "GNUNET_LOG" only affects the logging when no global log level is
-configured by any other means (that is, the process does not explicitly
-set its own log level, there are no "-L loglevel" options on command line
-or in configuration files), and can be used to override the default
-WARNING log level.
-
-@item "GNUNET_FORCE_LOG" will completely override any other log
-configuration options given.
-
-@item "GNUNET_FORCE_LOGFILE" will completely override the location of the
-file to log messages to. It should contain a relative or absolute file
-name. Setting GNUNET_FORCE_LOGFILE is equivalent to passing
-"--log-file=logfile" or "-l logfile" option (see below). It supports "[]"
-format in file names, but not "@{@}" (see below).
-@end itemize
-
-
-Because environment variables are inherited by child processes when they
-are launched, starting or re-starting the ARM service with these
-variables will propagate them to all other services.
-
-"GNUNET_LOG" and "GNUNET_FORCE_LOG" variables must contain a specially
-formatted @strong{logging definition} string, which looks like this:@
-
-@example
-[component];[file];[function];[from_line[-to_line]];loglevel[/component...]
-@end example
-
-That is, a logging definition consists of definition entries, separated by
-slashes ('/'). If only one entry is present, there is no need to add a
-slash to its end (although it is not forbidden either).@ All definition
-fields (component, file, function, lines and loglevel) are mandatory, but
-(except for the loglevel) they can be empty. An empty field means
-"match anything". Note that even if fields are empty, the semicolon (';')
-separators must be present.@ The loglevel field is mandatory, and must
-contain one of the log level names (ERROR, WARNING, INFO or DEBUG).@
-The lines field might contain one non-negative number, in which case it
-matches only one line, or a range "from_line-to_line", in which case it
-matches any line in the interval [from_line;to_line] (that is, including
-both start and end line).@ GNUnet mostly defaults component name to the
-name of the service that is implemented in a process ('transport',
-'core', 'peerinfo', etc), but logging calls can specify custom component
-names using @code{GNUNET_log_from}.@ File name and function name are
-provided by the compiler (__FILE__ and __FUNCTION__ built-ins).
-
-Component, file and function fields are interpreted as non-extended
-regular expressions (GNU libc regex functions are used). Matching is
-case-sensitive, "^" and "$" will match the beginning and the end of the
-text. If a field is empty, its contents are automatically replaced with
-a ".*" regular expression, which matches anything. Matching is done in
-the default way, which means that the expression matches as long as it's
-contained anywhere in the string. Thus "GNUNET_" will match both
-"GNUNET_foo" and "BAR_GNUNET_BAZ". Use '^' and/or '$' to make sure that
-the expression matches at the start and/or at the end of the string.
-The semicolon (';') can't be escaped, and GNUnet will not use it in
-component names (it can't be used in function names and file names
-anyway).
-
-@end table
-
-
-Every logging call in GNUnet code will be (at run time) matched against
-the log definitions passed to the process. If a log definition fields are
-matching the call arguments, then the call log level is compared the the
-log level of that definition. If the call log level is less or equal to
-the definition log level, the call is allowed to proceed. Otherwise the
-logging call is forbidden, and nothing is logged. If no definitions
-matched at all, GNUnet will use the global log level or (if a global log
-level is not specified) will default to WARNING (that is, it will allow
-the call to proceed, if its level is less or equal to the global log
-level or to WARNING).
-
-That is, definitions are evaluated from left to right, and the first
-matching definition is used to allow or deny the logging call. Thus it is
-advised to place narrow definitions at the beginning of the logdef
-string, and generic definitions - at the end.
-
-Whether a call is allowed or not is only decided the first time this
-particular call is made. The evaluation result is then cached, so that
-any attempts to make the same call later will be allowed or disallowed
-right away. Because of that runtime log level evaluation should not
-significantly affect the process performance.
-Log definition parsing is only done once, at the first call to
-GNUNET_log_setup () made by the process (which is usually done soon after
-it starts).
-
-At the moment of writing there is no way to specify logging definitions
-from configuration files, only via environment variables.
-
-At the moment GNUnet will stop processing a log definition when it
-encounters an error in definition formatting or an error in regular
-expression syntax, and will not report the failure in any way.
-
-
-@c ***********************************************************************
-@menu
-* Examples::
-* Log files::
-* Updated behavior of GNUNET_log::
-@end menu
-
-@node Examples
-@subsubsection Examples
-
-@table @asis
-
-@item @code{GNUNET_FORCE_LOG=";;;;DEBUG" gnunet-arm -s} Start GNUnet
-process tree, running all processes with DEBUG level (one should be
-careful with it, as log files will grow at alarming rate!)
-@item @code{GNUNET_FORCE_LOG="core;;;;DEBUG" gnunet-arm -s} Start GNUnet
-process tree, running the core service under DEBUG level (everything else
-will use configured or default level).
-
-@item Start GNUnet process tree, allowing any logging calls from
-gnunet-service-transport_validation.c (everything else will use
-configured or default level).
-
-@example
-GNUNET_FORCE_LOG=";gnunet-service-transport_validation.c;;; DEBUG" \
-gnunet-arm -s
-@end example
-
-@item Start GNUnet process tree, allowing any logging calls from
-gnunet-gnunet-service-fs_push.c (everything else will use configured or
-default level).
-
-@example
-GNUNET_FORCE_LOG="fs;gnunet-service-fs_push.c;;;DEBUG" gnunet-arm -s
-@end example
-
-@item Start GNUnet process tree, allowing any logging calls from the
-GNUNET_NETWORK_socket_select function (everything else will use
-configured or default level).
-
-@example
-GNUNET_FORCE_LOG=";;GNUNET_NETWORK_socket_select;;DEBUG" gnunet-arm -s
-@end example
-
-@item Start GNUnet process tree, allowing any logging calls from the
-components that have "transport" in their names, and are made from
-function that have "send" in their names. Everything else will be allowed
-to be logged only if it has WARNING level.
-
-@example
-GNUNET_FORCE_LOG="transport.*;;.*send.*;;DEBUG/;;;;WARNING" gnunet-arm -s
-@end example
-
-@end table
-
-
-On Windows, one can use batch files to run GNUnet processes with special
-environment variables, without affecting the whole system. Such batch
-file will look like this:
-
-@example
-set GNUNET_FORCE_LOG=;;do_transmit;;DEBUG@ gnunet-arm -s
-@end example
-
-(note the absence of double quotes in the environment variable definition,
-as opposed to earlier examples, which use the shell).
-Another limitation, on Windows, GNUNET_FORCE_LOGFILE @strong{MUST} be set
-in order to GNUNET_FORCE_LOG to work.
-
-
-@c ***********************************************************************
-@node Log files
-@subsubsection Log files
-
-GNUnet can be told to log everything into a file instead of stderr (which
-is the default) using the "--log-file=logfile" or "-l logfile" option.
-This option can also be passed via command line, or from the "OPTION" and
-"GLOBAL_POSTFIX" configuration keys (see above). The file name passed
-with this option is subject to GNUnet filename expansion. If specified in
-"GLOBAL_POSTFIX", it is also subject to ARM service filename expansion,
-in particular, it may contain "@{@}" (left and right curly brace)
-sequence, which will be replaced by ARM with the name of the service.
-This is used to keep logs from more than one service separate, while only
-specifying one template containing "@{@}" in GLOBAL_POSTFIX.
-
-As part of a secondary file name expansion, the first occurrence of "[]"
-sequence ("left square brace" followed by "right square brace") in the
-file name will be replaced with a process identifier or the process when
-it initializes its logging subsystem. As a result, all processes will log
-into different files. This is convenient for isolating messages of a
-particular process, and prevents I/O races when multiple processes try to
-write into the file at the same time. This expansion is done
-independently of "@{@}" expansion that ARM service does (see above).
-
-The log file name that is specified via "-l" can contain format characters
-from the 'strftime' function family. For example, "%Y" will be replaced
-with the current year. Using "basename-%Y-%m-%d.log" would include the
-current year, month and day in the log file. If a GNUnet process runs for
-long enough to need more than one log file, it will eventually clean up
-old log files. Currently, only the last three log files (plus the current
-log file) are preserved. So once the fifth log file goes into use (so
-after 4 days if you use "%Y-%m-%d" as above), the first log file will be
-automatically deleted. Note that if your log file name only contains "%Y",
-then log files would be kept for 4 years and the logs from the first year
-would be deleted once year 5 begins. If you do not use any date-related
-string format codes, logs would never be automatically deleted by GNUnet.
-
-
-@c ***********************************************************************
-
-@node Updated behavior of GNUNET_log
-@subsubsection Updated behavior of GNUNET_log
-
-It's currently quite common to see constructions like this all over the
-code:
-
-@example
-#if MESH_DEBUG
-GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: client disconnected\n");
-#endif
-@end example
-
-The reason for the #if is not to avoid displaying the message when
-disabled (GNUNET_ERROR_TYPE takes care of that), but to avoid the
-compiler including it in the binary at all, when compiling GNUnet for
-platforms with restricted storage space / memory (MIPS routers,
-ARM plug computers / dev boards, etc).
-
-This presents several problems: the code gets ugly, hard to write and it
-is very easy to forget to include the #if guards, creating non-consistent
-code. A new change in GNUNET_log aims to solve these problems.
-
-@strong{This change requires to @file{./configure} with at least
-@code{--enable-logging=verbose} to see debug messages.}
-
-Here is an example of code with dense debug statements:
-
-@example
-switch (restrict_topology) @{
-case GNUNET_TESTING_TOPOLOGY_CLIQUE:#if VERBOSE_TESTING
-GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Blacklisting all but clique
-topology\n")); #endif unblacklisted_connections = create_clique (pg,
-&remove_connections, BLACKLIST, GNUNET_NO); break; case
-GNUNET_TESTING_TOPOLOGY_SMALL_WORLD_RING: #if VERBOSE_TESTING GNUNET_log
-(GNUNET_ERROR_TYPE_DEBUG, _("Blacklisting all but small world (ring)
-topology\n")); #endif unblacklisted_connections = create_small_world_ring
-(pg,&remove_connections, BLACKLIST); break;
-@end example
-
-
-Pretty hard to follow, huh?
-
-From now on, it is not necessary to include the #if / #endif statements to
-achieve the same behavior. The GNUNET_log and GNUNET_log_from macros take
-care of it for you, depending on the configure option:
-
-@itemize @bullet
-@item If @code{--enable-logging} is set to @code{no}, the binary will
-contain no log messages at all.
-@item If @code{--enable-logging} is set to @code{yes}, the binary will
-contain no DEBUG messages, and therefore running with -L DEBUG will have
-no effect. Other messages (ERROR, WARNING, INFO, etc) will be included.
-@item If @code{--enable-logging} is set to @code{verbose}, or
-@code{veryverbose} the binary will contain DEBUG messages (still, it will
-be neccessary to run with -L DEBUG or set the DEBUG config option to show
-them).
-@end itemize
-
-
-If you are a developer:
-@itemize @bullet
-@item please make sure that you @code{./configure
---enable-logging=@{verbose,veryverbose@}}, so you can see DEBUG messages.
-@item please remove the @code{#if} statements around @code{GNUNET_log
-(GNUNET_ERROR_TYPE_DEBUG, ...)} lines, to improve the readibility of your
-code.
-@end itemize
-
-Since now activating DEBUG automatically makes it VERBOSE and activates
-@strong{all} debug messages by default, you probably want to use the
-https://gnunet.org/logging functionality to filter only relevant messages.
-A suitable configuration could be:
-
-@example
-$ export GNUNET_FORCE_LOG="^YOUR_SUBSYSTEM$;;;;DEBUG/;;;;WARNING"
-@end example
-
-Which will behave almost like enabling DEBUG in that subsytem before the
-change. Of course you can adapt it to your particular needs, this is only
-a quick example.
-
-@c ***********************************************************************
-@node Interprocess communication API (IPC)
-@subsection Interprocess communication API (IPC)
-
-In GNUnet a variety of new message types might be defined and used in
-interprocess communication, in this tutorial we use the
-@code{struct AddressLookupMessage} as a example to introduce how to
-construct our own message type in GNUnet and how to implement the message
-communication between service and client.
-(Here, a client uses the @code{struct AddressLookupMessage} as a request
-to ask the server to return the address of any other peer connecting to
-the service.)
-
-
-@c ***********************************************************************
-@menu
-* Define new message types::
-* Define message struct::
-* Client - Establish connection::
-* Client - Initialize request message::
-* Client - Send request and receive response::
-* Server - Startup service::
-* Server - Add new handles for specified messages::
-* Server - Process request message::
-* Server - Response to client::
-* Server - Notification of clients::
-* Conversion between Network Byte Order (Big Endian) and Host Byte Order::
-@end menu
-
-@node Define new message types
-@subsubsection Define new message types
-
-First of all, you should define the new message type in
-@file{gnunet_protocols.h}:
-
-@example
- // Request to look addresses of peers in server.
-#define GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_LOOKUP 29
- // Response to the address lookup request.
-#define GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_REPLY 30
-@end example
-
-@c ***********************************************************************
-@node Define message struct
-@subsubsection Define message struct
-
-After the type definition, the specified message structure should also be
-described in the header file, e.g. transport.h in our case.
-@example
-GNUNET_NETWORK_STRUCT_BEGIN
-
-struct AddressLookupMessage @{ struct GNUNET_MessageHeader header; int32_t
-numeric_only GNUNET_PACKED; struct GNUNET_TIME_AbsoluteNBO timeout; uint32_t
-addrlen GNUNET_PACKED;
- /* followed by 'addrlen' bytes of the actual address, then
- followed by the 0-terminated name of the transport */ @};
- GNUNET_NETWORK_STRUCT_END
-@end example
-
-
-Please note @code{GNUNET_NETWORK_STRUCT_BEGIN} and @code{GNUNET_PACKED}
-which both ensure correct alignment when sending structs over the network.
-
-@menu
-@end menu
-
-@c ***********************************************************************
-@node Client - Establish connection
-@subsubsection Client - Establish connection
-@c %**end of header
-
-
-At first, on the client side, the underlying API is employed to create a
-new connection to a service, in our example the transport service would be
-connected.
-
-@example
-struct GNUNET_CLIENT_Connection *client; client =
-GNUNET_CLIENT_connect ("transport", cfg);
-@end example
-
-@c ***********************************************************************
-@node Client - Initialize request message
-@subsubsection Client - Initialize request message
-@c %**end of header
-
-When the connection is ready, we initialize the message. In this step,
-all the fields of the message should be properly initialized, namely the
-size, type, and some extra user-defined data, such as timeout, name of
-transport, address and name of transport.
-
-@example
-struct AddressLookupMessage *msg; size_t len =
-sizeof (struct AddressLookupMessage) + addressLen + strlen (nameTrans) + 1;
-msg->header->size = htons (len); msg->header->type = htons
-(GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_LOOKUP); msg->timeout =
-GNUNET_TIME_absolute_hton (abs_timeout); msg->addrlen = htonl (addressLen);
-char *addrbuf = (char *) &msg[1]; memcpy (addrbuf, address, addressLen); char
-*tbuf = &addrbuf[addressLen]; memcpy (tbuf, nameTrans, strlen (nameTrans) + 1);
-@end example
-
-Note that, here the functions @code{htonl}, @code{htons} and
-@code{GNUNET_TIME_absolute_hton} are applied to convert little endian
-into big endian, about the usage of the big/small edian order and the
-corresponding conversion function please refer to Introduction of
-Big Endian and Little Endian.
-
-@c ***********************************************************************
-@node Client - Send request and receive response
-@subsubsection Client - Send request and receive response
-@c %**end of header
-
-@b{FIXME: This is very outdated, see the tutorial for the current API!}
-
-Next, the client would send the constructed message as a request to the
-service and wait for the response from the service. To accomplish this
-goal, there are a number of API calls that can be used. In this example,
-@code{GNUNET_CLIENT_transmit_and_get_response} is chosen as the most
-appropriate function to use.
-
-@example
-GNUNET_CLIENT_transmit_and_get_response
-(client, msg->header, timeout, GNUNET_YES, &address_response_processor,
-arp_ctx);
-@end example
-
-the argument @code{address_response_processor} is a function with
-@code{GNUNET_CLIENT_MessageHandler} type, which is used to process the
-reply message from the service.
-
-@node Server - Startup service
-@subsubsection Server - Startup service
-
-After receiving the request message, we run a standard GNUnet service
-startup sequence using @code{GNUNET_SERVICE_run}, as follows,
-
-@example
-int main(int
-argc, char**argv) @{ GNUNET_SERVICE_run(argc, argv, "transport"
-GNUNET_SERVICE_OPTION_NONE, &run, NULL)); @}
-@end example
-
-@c ***********************************************************************
-@node Server - Add new handles for specified messages
-@subsubsection Server - Add new handles for specified messages
-@c %**end of header
-
-in the function above the argument @code{run} is used to initiate
-transport service,and defined like this:
-
-@example
-static void run (void *cls, struct
-GNUNET_SERVER_Handle *serv, const struct GNUNET_CONFIGURATION_Handle *cfg) @{
-GNUNET_SERVER_add_handlers (serv, handlers); @}
-@end example
-
-
-Here, @code{GNUNET_SERVER_add_handlers} must be called in the run
-function to add new handlers in the service. The parameter
-@code{handlers} is a list of @code{struct GNUNET_SERVER_MessageHandler}
-to tell the service which function should be called when a particular
-type of message is received, and should be defined in this way:
-
-@example
-static struct GNUNET_SERVER_MessageHandler
-handlers[] = @{ @{&handle_start, NULL, GNUNET_MESSAGE_TYPE_TRANSPORT_START,
-0@}, @{&handle_send, NULL, GNUNET_MESSAGE_TYPE_TRANSPORT_SEND, 0@},
-@{&handle_try_connect, NULL, GNUNET_MESSAGE_TYPE_TRANSPORT_TRY_CONNECT, sizeof
-(struct TryConnectMessage)@}, @{&handle_address_lookup, NULL,
-GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_LOOKUP, 0@}, @{NULL, NULL, 0, 0@} @};
-@end example
-
-
-As shown, the first member of the struct in the first area is a callback
-function, which is called to process the specified message types, given
-as the third member. The second parameter is the closure for the callback
-function, which is set to @code{NULL} in most cases, and the last
-parameter is the expected size of the message of this type, usually we
-set it to 0 to accept variable size, for special cases the exact size of
-the specified message also can be set. In addition, the terminator sign
-depicted as @code{@{NULL, NULL, 0, 0@}} is set in the last aera.
-
-@c ***********************************************************************
-@node Server - Process request message
-@subsubsection Server - Process request message
-@c %**end of header
-
-After the initialization of transport service, the request message would
-be processed. Before handling the main message data, the validity of this
-message should be checked out, e.g., to check whether the size of message
-is correct.
-
-@example
-size = ntohs (message->size); if (size < sizeof (struct
-AddressLookupMessage)) @{ GNUNET_break_op (0); GNUNET_SERVER_receive_done
-(client, GNUNET_SYSERR); return; @}
-@end example
-
-
-Note that, opposite to the construction method of the request message in
-the client, in the server the function @code{nothl} and @code{ntohs}
-should be employed during the extraction of the data from the message, so
-that the data in big endian order can be converted back into little
-endian order. See more in detail please refer to Introduction of
-Big Endian and Little Endian.
-
-Moreover in this example, the name of the transport stored in the message
-is a 0-terminated string, so we should also check whether the name of the
-transport in the received message is 0-terminated:
-
-@example
-nameTransport = (const char *)
-&address[addressLen]; if (nameTransport[size - sizeof (struct
-AddressLookupMessage)
- - addressLen - 1] != '\0') @{ GNUNET_break_op
- (0); GNUNET_SERVER_receive_done (client,
- GNUNET_SYSERR); return; @}
-@end example
-
-Here, @code{GNUNET_SERVER_receive_done} should be called to tell the
-service that the request is done and can receive the next message. The
-argument @code{GNUNET_SYSERR} here indicates that the service didn't
-understand the request message, and the processing of this request would
-be terminated.
-
-In comparison to the aforementioned situation, when the argument is equal
-to @code{GNUNET_OK}, the service would continue to process the requst
-message.
-
-@c ***********************************************************************
-@node Server - Response to client
-@subsubsection Server - Response to client
-@c %**end of header
-
-Once the processing of current request is done, the server should give the
-response to the client. A new @code{struct AddressLookupMessage} would be
-produced by the server in a similar way as the client did and sent to the
-client, but here the type should be
-@code{GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_REPLY} rather than
-@code{GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_LOOKUP} in client.
-@example
-struct
-AddressLookupMessage *msg; size_t len = sizeof (struct AddressLookupMessage) +
-addressLen + strlen (nameTrans) + 1; msg->header->size = htons (len);
-msg->header->type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_REPLY);
-
-// ...
-
-struct GNUNET_SERVER_TransmitContext *tc; tc =
-GNUNET_SERVER_transmit_context_create (client);
-GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0,
-GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_REPLY);
-GNUNET_SERVER_transmit_context_run (tc, rtimeout);
-@end example
-
-
-Note that, there are also a number of other APIs provided to the service
-to send the message.
-
-@c ***********************************************************************
-@node Server - Notification of clients
-@subsubsection Server - Notification of clients
-@c %**end of header
-
-Often a service needs to (repeatedly) transmit notifications to a client
-or a group of clients. In these cases, the client typically has once
-registered for a set of events and then needs to receive a message
-whenever such an event happens (until the client disconnects). The use of
-a notification context can help manage message queues to clients and
-handle disconnects. Notification contexts can be used to send
-individualized messages to a particular client or to broadcast messages
-to a group of clients. An individualized notification might look like
-this:
-
-@example
- GNUNET_SERVER_notification_context_unicast(nc,
- client, msg, GNUNET_YES);
-@end example
-
-
-Note that after processing the original registration message for
-notifications, the server code still typically needs to call
-@code{GNUNET_SERVER_receive_done} so that the client can transmit further
-messages to the server.
-
-@c ***********************************************************************
-@node Conversion between Network Byte Order (Big Endian) and Host Byte Order
-@subsubsection Conversion between Network Byte Order (Big Endian) and Host Byte Order
-@c %** subsub? it's a referenced page on the ipc document.
-@c %**end of header
-
-Here we can simply comprehend big endian and little endian as Network Byte
-Order and Host Byte Order respectively. What is the difference between
-both two?
-
-Usually in our host computer we store the data byte as Host Byte Order,
-for example, we store a integer in the RAM which might occupies 4 Byte,
-as Host Byte Order the higher Byte would be stored at the lower address
-of RAM, and the lower Byte would be stored at the higher address of RAM.
-However, contrast to this, Network Byte Order just take the totally
-opposite way to store the data, says, it will store the lower Byte at the
-lower address, and the higher Byte will stay at higher address.
-
-For the current communication of network, we normally exchange the
-information by surveying the data package, every two host wants to
-communicate with each other must send and receive data package through
-network. In order to maintain the identity of data through the
-transmission in the network, the order of the Byte storage must changed
-before sending and after receiving the data.
-
-There ten convenient functions to realize the conversion of Byte Order in
-GNUnet, as following:
-
-@table @asis
-
-@item uint16_t htons(uint16_t hostshort) Convert host byte order to net
-byte order with short int
-@item uint32_t htonl(uint32_t hostlong) Convert host byte
-order to net byte order with long int
-@item uint16_t ntohs(uint16_t netshort)
-Convert net byte order to host byte order with short int
-@item uint32_t
-ntohl(uint32_t netlong) Convert net byte order to host byte order with
-long int
-@item unsigned long long GNUNET_ntohll (unsigned long long netlonglong)
-Convert net byte order to host byte order with long long int
-@item unsigned long long GNUNET_htonll (unsigned long long hostlonglong)
-Convert host byte order to net byte order with long long int
-@item struct GNUNET_TIME_RelativeNBO GNUNET_TIME_relative_hton
-(struct GNUNET_TIME_Relative a) Convert relative time to network byte
-order.
-@item struct GNUNET_TIME_Relative GNUNET_TIME_relative_ntoh
-(struct GNUNET_TIME_RelativeNBO a) Convert relative time from network
-byte order.
-@item struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton
-(struct GNUNET_TIME_Absolute a) Convert relative time to network byte
-order.
-@item struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh
-(struct GNUNET_TIME_AbsoluteNBO a) Convert relative time from network
-byte order.
-@end table
-
-@c ***********************************************************************
-
-@node Cryptography API
-@subsection Cryptography API
-@c %**end of header
-
-The gnunetutil APIs provides the cryptographic primitives used in GNUnet.
-GNUnet uses 2048 bit RSA keys for the session key exchange and for signing
-messages by peers and most other public-key operations. Most researchers
-in cryptography consider 2048 bit RSA keys as secure and practically
-unbreakable for a long time. The API provides functions to create a fresh
-key pair, read a private key from a file (or create a new file if the
-file does not exist), encrypt, decrypt, sign, verify and extraction of
-the public key into a format suitable for network transmission.
-
-For the encryption of files and the actual data exchanged between peers
-GNUnet uses 256-bit AES encryption. Fresh, session keys are negotiated
-for every new connection.@ Again, there is no published technique to
-break this cipher in any realistic amount of time. The API provides
-functions for generation of keys, validation of keys (important for
-checking that decryptions using RSA succeeded), encryption and decryption.
-
-GNUnet uses SHA-512 for computing one-way hash codes. The API provides
-functions to compute a hash over a block in memory or over a file on disk.
-
-The crypto API also provides functions for randomizing a block of memory,
-obtaining a single random number and for generating a permuation of the
-numbers 0 to n-1. Random number generation distinguishes between WEAK and
-STRONG random number quality; WEAK random numbers are pseudo-random
-whereas STRONG random numbers use entropy gathered from the operating
-system.
-
-Finally, the crypto API provides a means to deterministically generate a
-1024-bit RSA key from a hash code. These functions should most likely not
-be used by most applications; most importantly,
-GNUNET_CRYPTO_rsa_key_create_from_hash does not create an RSA-key that
-should be considered secure for traditional applications of RSA.
-
-@c ***********************************************************************
-@node Message Queue API
-@subsection Message Queue API
-@c %**end of header
-
-@strong{ Introduction }@
-Often, applications need to queue messages that
-are to be sent to other GNUnet peers, clients or services. As all of
-GNUnet's message-based communication APIs, by design, do not allow
-messages to be queued, it is common to implement custom message queues
-manually when they are needed. However, writing very similar code in
-multiple places is tedious and leads to code duplication.
-
-MQ (for Message Queue) is an API that provides the functionality to
-implement and use message queues. We intend to eventually replace all of
-the custom message queue implementations in GNUnet with MQ.
-
-@strong{ Basic Concepts }@
-The two most important entities in MQ are queues and envelopes.
-
-Every queue is backed by a specific implementation (e.g. for mesh, stream,
-connection, server client, etc.) that will actually deliver the queued
-messages. For convenience,@ some queues also allow to specify a list of
-message handlers. The message queue will then also wait for incoming
-messages and dispatch them appropriately.
-
-An envelope holds the the memory for a message, as well as metadata
-(Where is the envelope queued? What should happen after it has been
-sent?). Any envelope can only be queued in one message queue.
-
-@strong{ Creating Queues }@
-The following is a list of currently available message queues. Note that
-to avoid layering issues, message queues for higher level APIs are not
-part of @code{libgnunetutil}, but@ the respective API itself provides the
-queue implementation.
-
-@table @asis
-
-@item @code{GNUNET_MQ_queue_for_connection_client}
-Transmits queued messages over a @code{GNUNET_CLIENT_Connection} handle.
-Also supports receiving with message handlers.
-
-@item @code{GNUNET_MQ_queue_for_server_client}
-Transmits queued messages over a @code{GNUNET_SERVER_Client} handle. Does
-not support incoming message handlers.
-
-@item @code{GNUNET_MESH_mq_create} Transmits queued messages over a
-@code{GNUNET_MESH_Tunnel} handle. Does not support incoming message
-handlers.
-
-@item @code{GNUNET_MQ_queue_for_callbacks} This is the most general
-implementation. Instead of delivering and receiving messages with one of
-GNUnet's communication APIs, implementation callbacks are called. Refer to
-"Implementing Queues" for a more detailed explanation.
-@end table
-
-
-@strong{ Allocating Envelopes }@
-A GNUnet message (as defined by the GNUNET_MessageHeader) has three
-parts: The size, the type, and the body.
-
-MQ provides macros to allocate an envelope containing a message
-conveniently, automatically setting the size and type fields of the
-message.
-
-Consider the following simple message, with the body consisting of a
-single number value.
-@c why the empy code function?
-@code{}
-
-@example
-struct NumberMessage @{
- /** Type: GNUNET_MESSAGE_TYPE_EXAMPLE_1 */
- struct GNUNET_MessageHeader header; uint32_t number GNUNET_PACKED; @};
-@end example
-
-An envelope containing an instance of the NumberMessage can be
-constructed like this:
-
-@example
-struct GNUNET_MQ_Envelope *ev; struct NumberMessage *msg; ev =
-GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_EXAMPLE_1); msg->number = htonl (42);
-@end example
-
-In the above code, @code{GNUNET_MQ_msg} is a macro. The return value is
-the newly allocated envelope. The first argument must be a pointer to some
-@code{struct} containing a @code{struct GNUNET_MessageHeader header}
-field, while the second argument is the desired message type, in host
-byte order.
-
-The @code{msg} pointer now points to an allocated message, where the
-message type and the message size are already set. The message's size is
-inferred from the type of the @code{msg} pointer: It will be set to
-'sizeof(*msg)', properly converted to network byte order.
-
-If the message body's size is dynamic, the the macro
-@code{GNUNET_MQ_msg_extra} can be used to allocate an envelope whose
-message has additional space allocated after the @code{msg} structure.
-
-If no structure has been defined for the message,
-@code{GNUNET_MQ_msg_header_extra} can be used to allocate additional space
-after the message header. The first argument then must be a pointer to a
-@code{GNUNET_MessageHeader}.
-
-@strong{Envelope Properties}@
-A few functions in MQ allow to set additional properties on envelopes:
-
-@table @asis
-
-@item @code{GNUNET_MQ_notify_sent} Allows to specify a function that will
-be called once the envelope's message@ has been sent irrevocably.
-An envelope can be canceled precisely up to the@ point where the notify
-sent callback has been called.
-
-@item @code{GNUNET_MQ_disable_corking} No corking will be used when
-sending the message. Not every@ queue supports this flag, per default,
-envelopes are sent with corking.@
-
-@end table
-
-
-@strong{Sending Envelopes}@
-Once an envelope has been constructed, it can be queued for sending with
-@code{GNUNET_MQ_send}.
-
-Note that in order to avoid memory leaks, an envelope must either be sent
-(the queue will free it) or destroyed explicitly with
-@code{GNUNET_MQ_discard}.
-
-@strong{Canceling Envelopes}@
-An envelope queued with @code{GNUNET_MQ_send} can be canceled with
-@code{GNUNET_MQ_cancel}. Note that after the notify sent callback has
-been called, canceling a message results in undefined behavior.
-Thus it is unsafe to cancel an envelope that does not have a notify sent
-callback. When canceling an envelope, it is not necessary@ to call
-@code{GNUNET_MQ_discard}, and the envelope can't be sent again.
-
-@strong{ Implementing Queues }@
-@code{TODO}
-
-@c ***********************************************************************
-@node Service API
-@subsection Service API
-@c %**end of header
-
-Most GNUnet code lives in the form of services. Services are processes
-that offer an API for other components of the system to build on. Those
-other components can be command-line tools for users, graphical user
-interfaces or other services. Services provide their API using an IPC
-protocol. For this, each service must listen on either a TCP port or a
-UNIX domain socket; for this, the service implementation uses the server
-API. This use of server is exposed directly to the users of the service
-API. Thus, when using the service API, one is usually also often using
-large parts of the server API. The service API provides various
-convenience functions, such as parsing command-line arguments and the
-configuration file, which are not found in the server API.
-The dual to the service/server API is the client API, which can be used to
-access services.
-
-The most common way to start a service is to use the GNUNET_SERVICE_run
-function from the program's main function. GNUNET_SERVICE_run will then
-parse the command line and configuration files and, based on the options
-found there, start the server. It will then give back control to the main
-program, passing the server and the configuration to the
-GNUNET_SERVICE_Main callback. GNUNET_SERVICE_run will also take care of
-starting the scheduler loop. If this is inappropriate (for example,
-because the scheduler loop is already running), GNUNET_SERVICE_start and
-related functions provide an alternative to GNUNET_SERVICE_run.
-
-When starting a service, the service_name option is used to determine
-which sections in the configuration file should be used to configure the
-service. A typical value here is the name of the src/ sub-directory, for
-example "statistics". The same string would also be given to
-GNUNET_CLIENT_connect to access the service.
-
-Once a service has been initialized, the program should use the
-GNUNET_SERVICE_Main callback to register message handlers using
-GNUNET_SERVER_add_handlers. The service will already have registered a
-handler for the "TEST" message.
-
-The option bitfield (enum GNUNET_SERVICE_Options) determines how a service
-should behave during shutdown. There are three key strategies:
-
-@table @asis
-
-@item instant (GNUNET_SERVICE_OPTION_NONE) Upon receiving the shutdown
-signal from the scheduler, the service immediately terminates the server,
-closing all existing connections with clients.
-@item manual
-(GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN) The service does nothing by itself
-during shutdown. The main program will need to take the appropriate
-action by calling GNUNET_SERVER_destroy or GNUNET_SERVICE_stop (depending
-on how the service was initialized) to terminate the service. This method
-is used by gnunet-service-arm and rather uncommon.
-@item soft
-(GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN) Upon receiving the shutdown signal
-from the scheduler, the service immediately tells the server to stop
-listening for incoming clients. Requests from normal existing clients are
-still processed and the server/service terminates once all normal clients
-have disconnected. Clients that are not expected to ever disconnect (such
-as clients that monitor performance values) can be marked as 'monitor'
-clients using GNUNET_SERVER_client_mark_monitor. Those clients will
-continue to be processed until all 'normal' clients have disconnected.
-Then, the server will terminate, closing the monitor connections.
-This mode is for example used by 'statistics', allowing existing 'normal'
-clients to set (possibly persistent) statistic values before terminating.
-
-@end table
-
-@c ***********************************************************************
-@node Optimizing Memory Consumption of GNUnet's (Multi-) Hash Maps
-@subsection Optimizing Memory Consumption of GNUnet's (Multi-) Hash Maps
-@c %**end of header
-
-A commonly used data structure in GNUnet is a (multi-)hash map. It is most
-often used to map a peer identity to some data structure, but also to map
-arbitrary keys to values (for example to track requests in the distributed
-hash table or in file-sharing). As it is commonly used, the DHT is
-actually sometimes responsible for a large share of GNUnet's overall
-memory consumption (for some processes, 30% is not uncommon). The
-following text documents some API quirks (and their implications for
-applications) that were recently introduced to minimize the footprint of
-the hash map.
-
-
-@c ***********************************************************************
-@menu
-* Analysis::
-* Solution::
-* Migration::
-* Conclusion::
-* Availability::
-@end menu
-
-@node Analysis
-@subsubsection Analysis
-@c %**end of header
-
-The main reason for the "excessive" memory consumption by the hash map is
-that GNUnet uses 512-bit cryptographic hash codes --- and the
-(multi-)hash map also uses the same 512-bit 'struct GNUNET_HashCode'. As
-a result, storing just the keys requires 64 bytes of memory for each key.
-As some applications like to keep a large number of entries in the hash
-map (after all, that's what maps are good for), 64 bytes per hash is
-significant: keeping a pointer to the value and having a linked list for
-collisions consume between 8 and 16 bytes, and 'malloc' may add about the
-same overhead per allocation, putting us in the 16 to 32 byte per entry
-ballpark. Adding a 64-byte key then triples the overall memory
-requirement for the hash map.
-
-To make things "worse", most of the time storing the key in the hash map
-is not required: it is typically already in memory elsewhere! In most
-cases, the values stored in the hash map are some application-specific
-struct that _also_ contains the hash. Here is a simplified example:
-
-@example
-struct MyValue @{
-struct GNUNET_HashCode key; unsigned int my_data; @};
-
-// ...
-val = GNUNET_malloc (sizeof (struct MyValue)); val->key = key; val->my_data =
-42; GNUNET_CONTAINER_multihashmap_put (map, &key, val, ...);
-@end example
-
-This is a common pattern as later the entries might need to be removed,
-and at that time it is convenient to have the key immediately at hand:
-
-@example
-GNUNET_CONTAINER_multihashmap_remove (map, &val->key, val);
-@end example
-
-
-Note that here we end up with two times 64 bytes for the key, plus maybe
-64 bytes total for the rest of the 'struct MyValue' and the map entry in
-the hash map. The resulting redundant storage of the key increases
-overall memory consumption per entry from the "optimal" 128 bytes to 192
-bytes. This is not just an extreme example: overheads in practice are
-actually sometimes close to those highlighted in this example. This is
-especially true for maps with a significant number of entries, as there
-we tend to really try to keep the entries small.
-
-@c ***********************************************************************
-@node Solution
-@subsubsection Solution
-@c %**end of header
-
-The solution that has now been implemented is to @strong{optionally}
-allow the hash map to not make a (deep) copy of the hash but instead have
-a pointer to the hash/key in the entry. This reduces the memory
-consumption for the key from 64 bytes to 4 to 8 bytes. However, it can
-also only work if the key is actually stored in the entry (which is the
-case most of the time) and if the entry does not modify the key (which in
-all of the code I'm aware of has been always the case if there key is
-stored in the entry). Finally, when the client stores an entry in the
-hash map, it @strong{must} provide a pointer to the key within the entry,
-not just a pointer to a transient location of the key. If
-the client code does not meet these requirements, the result is a dangling
-pointer and undefined behavior of the (multi-)hash map API.
-
-@c ***********************************************************************
-@node Migration
-@subsubsection Migration
-@c %**end of header
-
-To use the new feature, first check that the values contain the respective
-key (and never modify it). Then, all calls to
-@code{GNUNET_CONTAINER_multihashmap_put} on the respective map must be
-audited and most likely changed to pass a pointer into the value's struct.
-For the initial example, the new code would look like this:
-
-@example
-struct MyValue @{
-struct GNUNET_HashCode key; unsigned int my_data; @};
-
-// ...
-val = GNUNET_malloc (sizeof (struct MyValue)); val->key = key; val->my_data =
-42; GNUNET_CONTAINER_multihashmap_put (map, &val->key, val, ...);
-@end example
-
-
-Note that @code{&val} was changed to @code{&val->key} in the argument to
-the @code{put} call. This is critical as often @code{key} is on the stack
-or in some other transient data structure and thus having the hash map
-keep a pointer to @code{key} would not work. Only the key inside of
-@code{val} has the same lifetime as the entry in the map (this must of
-course be checked as well). Naturally, @code{val->key} must be
-intiialized before the @code{put} call. Once all @code{put} calls have
-been converted and double-checked, you can change the call to create the
-hash map from
-
-@example
-map =
-GNUNET_CONTAINER_multihashmap_create (SIZE, GNUNET_NO);
-@end example
-
-to
-
-@example
-map = GNUNET_CONTAINER_multihashmap_create (SIZE, GNUNET_YES);
-@end example
-
-If everything was done correctly, you now use about 60 bytes less memory
-per entry in @code{map}. However, if now (or in the future) any call to
-@code{put} does not ensure that the given key is valid until the entry is
-removed from the map, undefined behavior is likely to be observed.
-
-@c ***********************************************************************
-@node Conclusion
-@subsubsection Conclusion
-@c %**end of header
-
-The new optimization can is often applicable and can result in a
-reduction in memory consumption of up to 30% in practice. However, it
-makes the code less robust as additional invariants are imposed on the
-multi hash map client. Thus applications should refrain from enabling the
-new mode unless the resulting performance increase is deemed significant
-enough. In particular, it should generally not be used in new code (wait
-at least until benchmarks exist).
-
-@c ***********************************************************************
-@node Availability
-@subsubsection Availability
-@c %**end of header
-
-The new multi hash map code was committed in SVN 24319 (will be in GNUnet
-0.9.4). Various subsystems (transport, core, dht, file-sharing) were
-previously audited and modified to take advantage of the new capability.
-In particular, memory consumption of the file-sharing service is expected
-to drop by 20-30% due to this change.
-
-@c ***********************************************************************
-@node The CONTAINER_MDLL API
-@subsection The CONTAINER_MDLL API
-@c %**end of header
-
-This text documents the GNUNET_CONTAINER_MDLL API. The
-GNUNET_CONTAINER_MDLL API is similar to the GNUNET_CONTAINER_DLL API in
-that it provides operations for the construction and manipulation of
-doubly-linked lists. The key difference to the (simpler) DLL-API is that
-the MDLL-version allows a single element (instance of a "struct") to be
-in multiple linked lists at the same time.
-
-Like the DLL API, the MDLL API stores (most of) the data structures for
-the doubly-linked list with the respective elements; only the 'head' and
-'tail' pointers are stored "elsewhere" --- and the application needs to
-provide the locations of head and tail to each of the calls in the
-MDLL API. The key difference for the MDLL API is that the "next" and
-"previous" pointers in the struct can no longer be simply called "next"
-and "prev" --- after all, the element may be in multiple doubly-linked
-lists, so we cannot just have one "next" and one "prev" pointer!
-
-The solution is to have multiple fields that must have a name of the
-format "next_XX" and "prev_XX" where "XX" is the name of one of the
-doubly-linked lists. Here is a simple example:
-
-@example
-struct MyMultiListElement @{
- struct MyMultiListElement *next_ALIST;
- struct MyMultiListElement *prev_ALIST;
- struct MyMultiListElement *next_BLIST;
- struct MyMultiListElement *prev_BLIST;
- void
- *data;
-@};
-@end example
-
-
-Note that by convention, we use all-uppercase letters for the list names.
-In addition, the program needs to have a location for the head and tail
-pointers for both lists, for example:
-
-@example
-static struct MyMultiListElement *head_ALIST;
-static struct MyMultiListElement *tail_ALIST;
-static struct MyMultiListElement *head_BLIST;
-static struct MyMultiListElement *tail_BLIST;
-@end example
-
-
-Using the MDLL-macros, we can now insert an element into the ALIST:
-
-@example
-GNUNET_CONTAINER_MDLL_insert (ALIST, head_ALIST, tail_ALIST, element);
-@end example
-
-
-Passing "ALIST" as the first argument to MDLL specifies which of the
-next/prev fields in the 'struct MyMultiListElement' should be used. The
-extra "ALIST" argument and the "_ALIST" in the names of the
-next/prev-members are the only differences between the MDDL and DLL-API.
-Like the DLL-API, the MDLL-API offers functions for inserting (at head,
-at tail, after a given element) and removing elements from the list.
-Iterating over the list should be done by directly accessing the
-"next_XX" and/or "prev_XX" members.
-
-@c ***********************************************************************
-@node The Automatic Restart Manager (ARM)
-@section The Automatic Restart Manager (ARM)
-@c %**end of header
-
-GNUnet's Automated Restart Manager (ARM) is the GNUnet service responsible
-for system initialization and service babysitting. ARM starts and halts
-services, detects configuration changes and restarts services impacted by
-the changes as needed. It's also responsible for restarting services in
-case of crashes and is planned to incorporate automatic debugging for
-diagnosing service crashes providing developers insights about crash
-reasons. The purpose of this document is to give GNUnet developer an idea
-about how ARM works and how to interact with it.
-
-@menu
-* Basic functionality::
-* Key configuration options::
-* Availability2::
-* Reliability::
-@end menu
-
-@c ***********************************************************************
-@node Basic functionality
-@subsection Basic functionality
-@c %**end of header
-
-@itemize @bullet
-@item ARM source code can be found under "src/arm".@ Service processes are
-managed by the functions in "gnunet-service-arm.c" which is controlled
-with "gnunet-arm.c" (main function in that file is ARM's entry point).
-
-@item The functions responsible for communicating with ARM , starting and
-stopping services -including ARM service itself- are provided by the
-ARM API "arm_api.c".@ Function: GNUNET_ARM_connect() returns to the caller
-an ARM handle after setting it to the caller's context (configuration and
-scheduler in use). This handle can be used afterwards by the caller to
-communicate with ARM. Functions GNUNET_ARM_start_service() and
-GNUNET_ARM_stop_service() are used for starting and stopping services
-respectively.
-
-@item A typical example of using these basic ARM services can be found in
-file test_arm_api.c. The test case connects to ARM, starts it, then uses
-it to start a service "resolver", stops the "resolver" then stops "ARM".
-@end itemize
-
-@c ***********************************************************************
-@node Key configuration options
-@subsection Key configuration options
-@c %**end of header
-
-Configurations for ARM and services should be available in a .conf file
-(As an example, see test_arm_api_data.conf). When running ARM, the
-configuration file to use should be passed to the command:@
-@code{@ $ gnunet-arm -s -c configuration_to_use.conf@ }@
-If no configuration is passed, the default configuration file will be used
-(see GNUNET_PREFIX/share/gnunet/defaults.conf which is created from
-contrib/defaults.conf).@ Each of the services is having a section starting
-by the service name between square brackets, for example: "[arm]".
-The following options configure how ARM configures or interacts with the
-various services:
-
-@table @asis
-
-@item PORT Port number on which the service is listening for incoming TCP
-connections. ARM will start the services should it notice a request at
-this port.
-
-@item HOSTNAME Specifies on which host the service is deployed. Note
-that ARM can only start services that are running on the local system
-(but will not check that the hostname matches the local machine name).
-This option is used by the @code{gnunet_client_lib.h} implementation to
-determine which system to connect to. The default is "localhost".
-
-@item BINARY The name of the service binary file.
-
-@item OPTIONS To be passed to the service.
-
-@item PREFIX A command to pre-pend to the actual command, for example,
-running a service with "valgrind" or "gdb"
-
-@item DEBUG Run in debug mode (much verbosity).
-
-@item AUTOSTART ARM will listen to UNIX domain socket and/or TCP port of
-the service and start the service on-demand.
-
-@item FORCESTART ARM will always start this service when the peer
-is started.
-
-@item ACCEPT_FROM IPv4 addresses the service accepts connections from.
-
-@item ACCEPT_FROM6 IPv6 addresses the service accepts connections from.
-
-@end table
-
-
-Options that impact the operation of ARM overall are in the "[arm]"
-section. ARM is a normal service and has (except for AUTOSTART) all of the
-options that other services do. In addition, ARM has the
-following options:
-
-@table @asis
-
-@item GLOBAL_PREFIX Command to be pre-pended to all services that are
-going to run.
-
-@item GLOBAL_POSTFIX Global option that will be supplied to all the
-services that are going to run.
-
-@end table
-
-@c ***********************************************************************
-@node Availability2
-@subsection Availability2
-@c %**end of header
-
-As mentioned before, one of the features provided by ARM is starting
-services on demand. Consider the example of one service "client" that
-wants to connect to another service a "server". The "client" will ask ARM
-to run the "server". ARM starts the "server". The "server" starts
-listening to incoming connections. The "client" will establish a
-connection with the "server". And then, they will start to communicate
-together.@ One problem with that scheme is that it's slow!@
-The "client" service wants to communicate with the "server" service at
-once and is not willing wait for it to be started and listening to
-incoming connections before serving its request.@ One solution for that
-problem will be that ARM starts all services as default services. That
-solution will solve the problem, yet, it's not quite practical, for some
-services that are going to be started can never be used or are going to
-be used after a relatively long time.@
-The approach followed by ARM to solve this problem is as follows:
-
-@itemize @bullet
-
-@item For each service having a PORT field in the configuration file and
-that is not one of the default services ( a service that accepts incoming
-connections from clients), ARM creates listening sockets for all addresses
-associated with that service.
-
-@item The "client" will immediately establish a connection with
-the "server".
-
-@item ARM --- pretending to be the "server" --- will listen on the
-respective port and notice the incoming connection from the "client"
-(but not accept it), instead
-
-@item Once there is an incoming connection, ARM will start the "server",
-passing on the listen sockets (now, the service is started and can do its
-work).
-
-@item Other client services now can directly connect directly to the
-"server".
-
-@end itemize
-
-@c ***********************************************************************
-@node Reliability
-@subsection Reliability
-
-One of the features provided by ARM, is the automatic restart of crashed
-services.@ ARM needs to know which of the running services died. Function
-"gnunet-service-arm.c/maint_child_death()" is responsible for that. The
-function is scheduled to run upon receiving a SIGCHLD signal. The
-function, then, iterates ARM's list of services running and monitors
-which service has died (crashed). For all crashing services, ARM restarts
-them.@
-Now, considering the case of a service having a serious problem causing it
-to crash each time it's started by ARM. If ARM keeps blindly restarting
-such a service, we are going to have the pattern:
-start-crash-restart-crash-restart-crash and so forth!! Which is of course
-not practical.@
-For that reason, ARM schedules the service to be restarted after waiting
-for some delay that grows exponentially with each crash/restart of that
-service.@ To clarify the idea, considering the following example:
-
-@itemize @bullet
-
-@item Service S crashed.
-
-@item ARM receives the SIGCHLD and inspects its list of services to find
-the dead one(s).
-
-@item ARM finds S dead and schedules it for restarting after "backoff"
-time which is initially set to 1ms. ARM will double the backoff time
-correspondent to S (now backoff(S) = 2ms)
-
-@item Because there is a severe problem with S, it crashed again.
-
-@item Again ARM receives the SIGCHLD and detects that it's S again that's
-crashed. ARM schedules it for restarting but after its new backoff time
-(which became 2ms), and doubles its backoff time (now backoff(S) = 4).
-
-@item and so on, until backoff(S) reaches a certain threshold
-(EXPONENTIAL_BACKOFF_THRESHOLD is set to half an hour), after reaching it,
-backoff(S) will remain half an hour, hence ARM won't be busy for a lot of
-time trying to restart a problematic service.
-@end itemize
-
-@c ***********************************************************************
-@node GNUnet's TRANSPORT Subsystem
-@section GNUnet's TRANSPORT Subsystem
-@c %**end of header
-
-This chapter documents how the GNUnet transport subsystem works. The
-GNUnet transport subsystem consists of three main components: the
-transport API (the interface used by the rest of the system to access the
-transport service), the transport service itself (most of the interesting
-functions, such as choosing transports, happens here) and the transport
-plugins. A transport plugin is a concrete implementation for how two
-GNUnet peers communicate; many plugins exist, for example for
-communication via TCP, UDP, HTTP, HTTPS and others. Finally, the
-transport subsystem uses supporting code, especially the NAT/UPnP
-library to help with tasks such as NAT traversal.
-
-Key tasks of the transport service include:
-
-@itemize @bullet
-
-@item Create our HELLO message, notify clients and neighbours if our HELLO
-changes (using NAT library as necessary)
-
-@item Validate HELLOs from other peers (send PING), allow other peers to
-validate our HELLO's addresses (send PONG)
-
-@item Upon request, establish connections to other peers (using address
-selection from ATS subsystem) and maintain them (again using PINGs and
-PONGs) as long as desired
-
-@item Accept incoming connections, give ATS service the opportunity to
-switch communication channels
-
-@item Notify clients about peers that have connected to us or that have
-been disconnected from us
-
-@item If a (stateful) connection goes down unexpectedly (without explicit
-DISCONNECT), quickly attempt to recover (without notifying clients) but do
-notify clients quickly if reconnecting fails
-
-@item Send (payload) messages arriving from clients to other peers via
-transport plugins and receive messages from other peers, forwarding
-those to clients
-
-@item Enforce inbound traffic limits (using flow-control if it is
-applicable); outbound traffic limits are enforced by CORE, not by us (!)
-
-@item Enforce restrictions on P2P connection as specified by the blacklist
-configuration and blacklisting clients
-@end itemize
-
-
-Note that the term "clients" in the list above really refers to the
-GNUnet-CORE service, as CORE is typically the only client of the
-transport service.
-
-@menu
-* Address validation protocol::
-@end menu
-
-@node Address validation protocol
-@subsection Address validation protocol
-@c %**end of header
-
-This section documents how the GNUnet transport service validates
-connections with other peers. It is a high-level description of the
-protocol necessary to understand the details of the implementation. It
-should be noted that when we talk about PING and PONG messages in this
-section, we refer to transport-level PING and PONG messages, which are
-different from core-level PING and PONG messages (both in implementation
-and function).
-
-The goal of transport-level address validation is to minimize the chances
-of a successful man-in-the-middle attack against GNUnet peers on the
-transport level. Such an attack would not allow the adversary to decrypt
-the P2P transmissions, but a successful attacker could at least measure
-traffic volumes and latencies (raising the adversaries capablities by
-those of a global passive adversary in the worst case). The scenarios we
-are concerned about is an attacker, Mallory, giving a HELLO to Alice that
-claims to be for Bob, but contains Mallory's IP address instead of Bobs
-(for some transport). Mallory would then forward the traffic to Bob (by
-initiating a connection to Bob and claiming to be Alice). As a further
-complication, the scheme has to work even if say Alice is behind a NAT
-without traversal support and hence has no address of her own (and thus
-Alice must always initiate the connection to Bob).
-
-An additional constraint is that HELLO messages do not contain a
-cryptographic signature since other peers must be able to edit
-(i.e. remove) addresses from the HELLO at any time (this was not true in
-GNUnet 0.8.x). A basic @strong{assumption} is that each peer knows the
-set of possible network addresses that it @strong{might} be reachable
-under (so for example, the external IP address of the NAT plus the LAN
-address(es) with the respective ports).
-
-The solution is the following. If Alice wants to validate that a given
-address for Bob is valid (i.e. is actually established @strong{directly}
-with the intended target), it sends a PING message over that connection
-to Bob. Note that in this case, Alice initiated the connection so only
-she knows which address was used for sure (Alice maybe behind NAT, so
-whatever address Bob sees may not be an address Alice knows she has). Bob
-checks that the address given in the PING is actually one of his addresses
-(does not belong to Mallory), and if it is, sends back a PONG (with a
-signature that says that Bob owns/uses the address from the PING). Alice
-checks the signature and is happy if it is valid and the address in the
-PONG is the address she used. This is similar to the 0.8.x protocol where
-the HELLO contained a signature from Bob for each address used by Bob.
-Here, the purpose code for the signature is
-@code{GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_OWN}. After this, Alice will
-remember Bob's address and consider the address valid for a while (12h in
-the current implementation). Note that after this exchange, Alice only
-considers Bob's address to be valid, the connection itself is not
-considered 'established'. In particular, Alice may have many addresses
-for Bob that she considers valid.
-
-The PONG message is protected with a nonce/challenge against replay
-attacks and uses an expiration time for the signature (but those are
-almost implementation details).
-
-@node NAT library
-@section NAT library
-@c %**end of header
-
-The goal of the GNUnet NAT library is to provide a general-purpose API for
-NAT traversal @strong{without} third-party support. So protocols that
-involve contacting a third peer to help establish a connection between
-two peers are outside of the scope of this API. That does not mean that
-GNUnet doesn't support involving a third peer (we can do this with the
-distance-vector transport or using application-level protocols), it just
-means that the NAT API is not concerned with this possibility. The API is
-written so that it will work for IPv6-NAT in the future as well as
-current IPv4-NAT. Furthermore, the NAT API is always used, even for peers
-that are not behind NAT --- in that case, the mapping provided is simply
-the identity.
-
-NAT traversal is initiated by calling @code{GNUNET_NAT_register}. Given a
-set of addresses that the peer has locally bound to (TCP or UDP), the NAT
-library will return (via callback) a (possibly longer) list of addresses
-the peer @strong{might} be reachable under. Internally, depending on the
-configuration, the NAT library will try to punch a hole (using UPnP) or
-just "know" that the NAT was manually punched and generate the respective
-external IP address (the one that should be globally visible) based on
-the given information.
-
-The NAT library also supports ICMP-based NAT traversal. Here, the other
-peer can request connection-reversal by this peer (in this special case,
-the peer is even allowed to configure a port number of zero). If the NAT
-library detects a connection-reversal request, it returns the respective
-target address to the client as well. It should be noted that
-connection-reversal is currently only intended for TCP, so other plugins
-@strong{must} pass @code{NULL} for the reversal callback. Naturally, the
-NAT library also supports requesting connection reversal from a remote
-peer (@code{GNUNET_NAT_run_client}).
-
-Once initialized, the NAT handle can be used to test if a given address is
-possibly a valid address for this peer (@code{GNUNET_NAT_test_address}).
-This is used for validating our addresses when generating PONGs.
-
-Finally, the NAT library contains an API to test if our NAT configuration
-is correct. Using @code{GNUNET_NAT_test_start} @strong{before} binding to
-the respective port, the NAT library can be used to test if the
-configuration works. The test function act as a local client, initialize
-the NAT traversal and then contact a @code{gnunet-nat-server} (running by
-default on @code{gnunet.org}) and ask for a connection to be established.
-This way, it is easy to test if the current NAT configuration is valid.
-
-@node Distance-Vector plugin
-@section Distance-Vector plugin
-@c %**end of header
-
-The Distance Vector (DV) transport is a transport mechanism that allows
-peers to act as relays for each other, thereby connecting peers that would
-otherwise be unable to connect. This gives a larger connection set to
-applications that may work better with more peers to choose from (for
-example, File Sharing and/or DHT).
-
-The Distance Vector transport essentially has two functions. The first is
-"gossiping" connection information about more distant peers to directly
-connected peers. The second is taking messages intended for non-directly
-connected peers and encapsulating them in a DV wrapper that contains the
-required information for routing the message through forwarding peers. Via
-gossiping, optimal routes through the known DV neighborhood are discovered
-and utilized and the message encapsulation provides some benefits in
-addition to simply getting the message from the correct source to the
-proper destination.
-
-The gossiping function of DV provides an up to date routing table of
-peers that are available up to some number of hops. We call this a
-fisheye view of the network (like a fish, nearby objects are known while
-more distant ones unknown). Gossip messages are sent only to directly
-connected peers, but they are sent about other knowns peers within the
-"fisheye distance". Whenever two peers connect, they immediately gossip
-to each other about their appropriate other neighbors. They also gossip
-about the newly connected peer to previously
-connected neighbors. In order to keep the routing tables up to date,
-disconnect notifications are propogated as gossip as well (because
-disconnects may not be sent/received, timeouts are also used remove
-stagnant routing table entries).
-
-Routing of messages via DV is straightforward. When the DV transport is
-notified of a message destined for a non-direct neighbor, the appropriate
-forwarding peer is selected, and the base message is encapsulated in a DV
-message which contains information about the initial peer and the intended
-recipient. At each forwarding hop, the initial peer is validated (the
-forwarding peer ensures that it has the initial peer in its neighborhood,
-otherwise the message is dropped). Next the base message is
-re-encapsulated in a new DV message for the next hop in the forwarding
-chain (or delivered to the current peer, if it has arrived at the
-destination).
-
-Assume a three peer network with peers Alice, Bob and Carol. Assume that
-Alice <-> Bob and Bob <-> Carol are direct (e.g. over TCP or UDP
-transports) connections, but that Alice cannot directly connect to Carol.
-This may be the case due to NAT or firewall restrictions, or perhaps
-based on one of the peers respective configurations. If the Distance
-Vector transport is enabled on all three peers, it will automatically
-discover (from the gossip protocol) that Alice and Carol can connect via
-Bob and provide a "virtual" Alice <-> Carol connection. Routing between
-Alice and Carol happens as follows; Alice creates a message destined for
-Carol and notifies the DV transport about it. The DV transport at Alice
-looks up Carol in the routing table and finds that the message must be
-sent through Bob for Carol. The message is encapsulated setting Alice as
-the initiator and Carol as the destination and sent to Bob. Bob receives
-the messages, verifies both Alice and Carol are known to Bob, and re-wraps
-the message in a new DV message for Carol. The DV transport at Carol
-receives this message, unwraps the original message, and delivers it to
-Carol as though it came directly from Alice.
-
-@node SMTP plugin
-@section SMTP plugin
-@c %**end of header
-
-This section describes the new SMTP transport plugin for GNUnet as it
-exists in the 0.7.x and 0.8.x branch. SMTP support is currently not
-available in GNUnet 0.9.x. This page also describes the transport layer
-abstraction (as it existed in 0.7.x and 0.8.x) in more detail and gives
-some benchmarking results. The performance results presented are quite
-old and maybe outdated at this point.
-
-@itemize @bullet
-@item Why use SMTP for a peer-to-peer transport?
-@item SMTPHow does it work?
-@item How do I configure my peer?
-@item How do I test if it works?
-@item How fast is it?
-@item Is there any additional documentation?
-@end itemize
-
-
-@menu
-* Why use SMTP for a peer-to-peer transport?::
-* How does it work?::
-* How do I configure my peer?::
-* How do I test if it works?::
-* How fast is it?::
-@end menu
-
-@node Why use SMTP for a peer-to-peer transport?
-@subsection Why use SMTP for a peer-to-peer transport?
-@c %**end of header
-
-There are many reasons why one would not want to use SMTP:
-
-@itemize @bullet
-@item SMTP is using more bandwidth than TCP, UDP or HTTP
-@item SMTP has a much higher latency.
-@item SMTP requires significantly more computation (encoding and decoding
-time) for the peers.
-@item SMTP is significantly more complicated to configure.
-@item SMTP may be abused by tricking GNUnet into sending mail to@
-non-participating third parties.
-@end itemize
-
-So why would anybody want to use SMTP?
-@itemize @bullet
-@item SMTP can be used to contact peers behind NAT boxes (in virtual
-private networks).
-@item SMTP can be used to circumvent policies that limit or prohibit
-peer-to-peer traffic by masking as "legitimate" traffic.
-@item SMTP uses E-mail addresses which are independent of a specific IP,
-which can be useful to address peers that use dynamic IP addresses.
-@item SMTP can be used to initiate a connection (e.g. initial address
-exchange) and peers can then negotiate the use of a more efficient
-protocol (e.g. TCP) for the actual communication.
-@end itemize
-
-In summary, SMTP can for example be used to send a message to a peer
-behind a NAT box that has a dynamic IP to tell the peer to establish a
-TCP connection to a peer outside of the private network. Even an
-extraordinary overhead for this first message would be irrelevant in this
-type of situation.
-
-@node How does it work?
-@subsection How does it work?
-@c %**end of header
-
-When a GNUnet peer needs to send a message to another GNUnet peer that has
-advertised (only) an SMTP transport address, GNUnet base64-encodes the
-message and sends it in an E-mail to the advertised address. The
-advertisement contains a filter which is placed in the E-mail header,
-such that the receiving host can filter the tagged E-mails and forward it
-to the GNUnet peer process. The filter can be specified individually by
-each peer and be changed over time. This makes it impossible to censor
-GNUnet E-mail messages by searching for a generic filter.
-
-@node How do I configure my peer?
-@subsection How do I configure my peer?
-@c %**end of header
-
-First, you need to configure @code{procmail} to filter your inbound E-mail
-for GNUnet traffic. The GNUnet messages must be delivered into a pipe, for
-example @code{/tmp/gnunet.smtp}. You also need to define a filter that is
-used by @command{procmail} to detect GNUnet messages. You are free to
-choose whichever filter you like, but you should make sure that it does
-not occur in your other E-mail. In our example, we will use
-@code{X-mailer: GNUnet}. The @code{~/.procmailrc} configuration file then
-looks like this:
-
-@example
-:0:
-* ^X-mailer: GNUnet
-/tmp/gnunet.smtp
-# where do you want your other e-mail delivered to (default: /var/spool/mail/)
-:0: /var/spool/mail/
-@end example
-
-After adding this file, first make sure that your regular E-mail still
-works (e.g. by sending an E-mail to yourself). Then edit the GNUnet
-configuration. In the section @code{SMTP} you need to specify your E-mail
-address under @code{EMAIL}, your mail server (for outgoing mail) under
-@code{SERVER}, the filter (X-mailer: GNUnet in the example) under
-@code{FILTER} and the name of the pipe under @code{PIPE}.@ The completed
-section could then look like this:
-
-@example
-EMAIL = me@@mail.gnu.org MTU = 65000 SERVER = mail.gnu.org:25 FILTER =
-"X-mailer: GNUnet" PIPE = /tmp/gnunet.smtp
-@end example
-
-Finally, you need to add @code{smtp} to the list of @code{TRANSPORTS} in
-the @code{GNUNETD} section. GNUnet peers will use the E-mail address that
-you specified to contact your peer until the advertisement times out.
-Thus, if you are not sure if everything works properly or if you are not
-planning to be online for a long time, you may want to configure this
-timeout to be short, e.g. just one hour. For this, set
-@code{HELLOEXPIRES} to @code{1} in the @code{GNUNETD} section.
-
-This should be it, but you may probably want to test it first.
-
-@node How do I test if it works?
-@subsection How do I test if it works?
-@c %**end of header
-
-Any transport can be subjected to some rudimentary tests using the
-@code{gnunet-transport-check} tool. The tool sends a message to the local
-node via the transport and checks that a valid message is received. While
-this test does not involve other peers and can not check if firewalls or
-other network obstacles prohibit proper operation, this is a great
-testcase for the SMTP transport since it tests pretty much nearly all of
-the functionality.
-
-@code{gnunet-transport-check} should only be used without running
-@code{gnunetd} at the same time. By default, @code{gnunet-transport-check}
-tests all transports that are specified in the configuration file. But
-you can specifically test SMTP by giving the option
-@code{--transport=smtp}.
-
-Note that this test always checks if a transport can receive and send.
-While you can configure most transports to only receive or only send
-messages, this test will only work if you have configured the transport
-to send and receive messages.
-
-@node How fast is it?
-@subsection How fast is it?
-@c %**end of header
-
-We have measured the performance of the UDP, TCP and SMTP transport layer
-directly and when used from an application using the GNUnet core.
-Measureing just the transport layer gives the better view of the actual
-overhead of the protocol, whereas evaluating the transport from the
-application puts the overhead into perspective from a practical point of
-view.
-
-The loopback measurements of the SMTP transport were performed on three
-different machines spanning a range of modern SMTP configurations. We
-used a PIII-800 running RedHat 7.3 with the Purdue Computer Science
-configuration which includes filters for spam. We also used a Xenon 2 GHZ
-with a vanilla RedHat 8.0 sendmail configuration. Furthermore, we used
-qmail on a PIII-1000 running Sorcerer GNU Linux (SGL). The numbers for
-UDP and TCP are provided using the SGL configuration. The qmail benchmark
-uses qmail's internal filtering whereas the sendmail benchmarks relies on
-procmail to filter and deliver the mail. We used the transport layer to
-send a message of b bytes (excluding transport protocol headers) directly
-to the local machine. This way, network latency and packet loss on the
-wire have no impact on the timings. n messages were sent sequentially over
-the transport layer, sending message i+1 after the i-th message was
-received. All messages were sent over the same connection and the time to
-establish the connection was not taken into account since this overhead is
-miniscule in practice --- as long as a connection is used for a
-significant number of messages.
-
-@multitable @columnfractions .20 .15 .15 .15 .15 .15
-@headitem Transport @tab UDP @tab TCP @tab SMTP (Purdue sendmail) @tab SMTP (RH 8.0) @tab SMTP (SGL qmail)
-@item 11 bytes @tab 31 ms @tab 55 ms @tab 781 s @tab 77 s @tab 24 s
-@item 407 bytes @tab 37 ms @tab 62 ms @tab 789 s @tab 78 s @tab 25 s
-@item 1,221 bytes @tab 46 ms @tab 73 ms @tab 804 s @tab 78 s @tab 25 s
-@end multitable
-
-The benchmarks show that UDP and TCP are, as expected, both significantly
-faster compared with any of the SMTP services. Among the SMTP
-implementations, there can be significant differences depending on the
-SMTP configuration. Filtering with an external tool like procmail that
-needs to re-parse its configuration for each mail can be very expensive.
-Applying spam filters can also significantly impact the performance of
-the underlying SMTP implementation. The microbenchmark shows that SMTP
-can be a viable solution for initiating peer-to-peer sessions: a couple of
-seconds to connect to a peer are probably not even going to be noticed by
-users. The next benchmark measures the possible throughput for a
-transport. Throughput can be measured by sending multiple messages in
-parallel and measuring packet loss. Note that not only UDP but also the
-TCP transport can actually loose messages since the TCP implementation
-drops messages if the @code{write} to the socket would block. While the
-SMTP protocol never drops messages itself, it is often so
-slow that only a fraction of the messages can be sent and received in the
-given time-bounds. For this benchmark we report the message loss after
-allowing t time for sending m messages. If messages were not sent (or
-received) after an overall timeout of t, they were considered lost. The
-benchmark was performed using two Xeon 2 GHZ machines running RedHat 8.0
-with sendmail. The machines were connected with a direct 100 MBit ethernet
-connection.@ Figures udp1200, tcp1200 and smtp-MTUs show that the
-throughput for messages of size 1,200 octects is 2,343 kbps, 3,310 kbps
-and 6 kbps for UDP, TCP and SMTP respectively. The high per-message
-overhead of SMTP can be improved by increasing the MTU, for example, an
-MTU of 12,000 octets improves the throughput to 13 kbps as figure
-smtp-MTUs shows. Our research paper) has some more details on the
-benchmarking results.
-
-@node Bluetooth plugin
-@section Bluetooth plugin
-@c %**end of header
-
-This page describes the new Bluetooth transport plugin for GNUnet. The
-plugin is still in the testing stage so don't expect it to work
-perfectly. If you have any questions or problems just post them here or
-ask on the IRC channel.
-
-@itemize @bullet
-@item What do I need to use the Bluetooth plugin transport?
-@item BluetoothHow does it work?
-@item What possible errors should I be aware of?
-@item How do I configure my peer?
-@item How can I test it?
-@end itemize
-
-
-
-@menu
-* What do I need to use the Bluetooth plugin transport?::
-* How does it work2?::
-* What possible errors should I be aware of?::
-* How do I configure my peer2?::
-* How can I test it?::
-* The implementation of the Bluetooth transport plugin::
-@end menu
-
-@node What do I need to use the Bluetooth plugin transport?
-@subsection What do I need to use the Bluetooth plugin transport?
-@c %**end of header
-
-If you are a Linux user and you want to use the Bluetooth transport plugin
-you should install the BlueZ development libraries (if they aren't already
-installed). For instructions about how to install the libraries you should
-check out the BlueZ site
-(@uref{http://www.bluez.org/, http://www.bluez.org}). If you don't know if
-you have the necesarry libraries, don't worry, just run the GNUnet
-configure script and you will be able to see a notification at the end
-which will warn you if you don't have the necessary libraries.
-
-If you are a Windows user you should have installed the
-@emph{MinGW}/@emph{MSys2} with the latest updates (especially the
-@emph{ws2bth} header). If this is your first build of GNUnet on Windows
-you should check out the SBuild repository. It will semi-automatically
-assembles a @emph{MinGW}/@emph{MSys2} installation with a lot of extra
-packages which are needed for the GNUnet build. So this will ease your
-work!@ Finally you just have to be sure that you have the correct drivers
-for your Bluetooth device installed and that your device is on and in a
-discoverable mode. The Windows Bluetooth Stack supports only the RFCOMM
-protocol so we cannot turn on your device programatically!
-
-@c FIXME: Change to unique title
-@node How does it work2?
-@subsection How does it work2?
-@c %**end of header
-
-The Bluetooth transport plugin uses virtually the same code as the WLAN
-plugin and only the helper binary is different. The helper takes a single
-argument, which represents the interface name and is specified in the
-configuration file. Here are the basic steps that are followed by the
-helper binary used on Linux:
-
-@itemize @bullet
-@item it verifies if the name corresponds to a Bluetooth interface name
-@item it verifies if the iterface is up (if it is not, it tries to bring
-it up)
-@item it tries to enable the page and inquiry scan in order to make the
-device discoverable and to accept incoming connection requests
-@emph{The above operations require root access so you should start the
-transport plugin with root privileges.}
-@item it finds an available port number and registers a SDP service which
-will be used to find out on which port number is the server listening on
-and switch the socket in listening mode
-@item it sends a HELLO message with its address
-@item finally it forwards traffic from the reading sockets to the STDOUT
-and from the STDIN to the writing socket
-@end itemize
-
-Once in a while the device will make an inquiry scan to discover the
-nearby devices and it will send them randomly HELLO messages for peer
-discovery.
-
-@node What possible errors should I be aware of?
-@subsection What possible errors should I be aware of?
-@c %**end of header
-
-@emph{This section is dedicated for Linux users}
-
-Well there are many ways in which things could go wrong but I will try to
-present some tools that you could use to debug and some scenarios.
-
-@itemize @bullet
-
-@item @code{bluetoothd -n -d} : use this command to enable logging in the
-foreground and to print the logging messages
-
-@item @code{hciconfig}: can be used to configure the Bluetooth devices.
-If you run it without any arguments it will print information about the
-state of the interfaces. So if you receive an error that the device
-couldn't be brought up you should try to bring it manually and to see if
-it works (use @code{hciconfig -a hciX up}). If you can't and the
-Bluetooth address has the form 00:00:00:00:00:00 it means that there is
-something wrong with the D-Bus daemon or with the Bluetooth daemon. Use
-@code{bluetoothd} tool to see the logs
-
-@item @code{sdptool} can be used to control and interogate SDP servers.
-If you encounter problems regarding the SDP server (like the SDP server is
-down) you should check out if the D-Bus daemon is running correctly and to
-see if the Bluetooth daemon started correctly(use @code{bluetoothd} tool).
-Also, sometimes the SDP service could work but somehow the device couldn't
-register his service. Use @code{sdptool browse [dev-address]} to see if
-the service is registered. There should be a service with the name of the
-interface and GNUnet as provider.
-
-@item @code{hcitool} : another useful tool which can be used to configure
-the device and to send some particular commands to it.
-
-@item @code{hcidump} : could be used for low level debugging
-@end itemize
-
-@c FIXME: A more unique name
-@node How do I configure my peer2?
-@subsection How do I configure my peer2?
-@c %**end of header
-
-On Linux, you just have to be sure that the interface name corresponds to
-the one that you want to use. Use the @code{hciconfig} tool to check that.
-By default it is set to hci0 but you can change it.
-
-A basic configuration looks like this:
-
-@example
-[transport-bluetooth]
-# Name of the interface (typically hciX)
-INTERFACE = hci0
-# Real hardware, no testing
-TESTMODE = 0 TESTING_IGNORE_KEYS = ACCEPT_FROM;
-@end example
-
-In order to use the Bluetooth transport plugin when the transport service
-is started, you must add the plugin name to the default transport service
-plugins list. For example:
-
-@example
-[transport] ... PLUGINS = dns bluetooth ...
-@end example
-
-If you want to use only the Bluetooth plugin set
-@emph{PLUGINS = bluetooth}
-
-On Windows, you cannot specify which device to use. The only thing that
-you should do is to add @emph{bluetooth} on the plugins list of the
-transport service.
-
-@node How can I test it?
-@subsection How can I test it?
-@c %**end of header
-
-If you have two Bluetooth devices on the same machine which use Linux you
-must:
-
-@itemize @bullet
-
-@item create two different file configuration (one which will use the
-first interface (@emph{hci0}) and the other which will use the second
-interface (@emph{hci1})). Let's name them @emph{peer1.conf} and
-@emph{peer2.conf}.
-
-@item run @emph{gnunet-peerinfo -c peerX.conf -s} in order to generate the
-peers private keys. The @strong{X} must be replace with 1 or 2.
-
-@item run @emph{gnunet-arm -c peerX.conf -s -i=transport} in order to
-start the transport service. (Make sure that you have "bluetooth" on the
-transport plugins list if the Bluetooth transport service doesn't start.)
-
-@item run @emph{gnunet-peerinfo -c peer1.conf -s} to get the first peer's
-ID. If you already know your peer ID (you saved it from the first
-command), this can be skipped.
-
-@item run @emph{gnunet-transport -c peer2.conf -p=PEER1_ID -s} to start
-sending data for benchmarking to the other peer.
-
-@end itemize
-
-
-This scenario will try to connect the second peer to the first one and
-then start sending data for benchmarking.
-
-On Windows you cannot test the plugin functionality using two Bluetooth
-devices from the same machine because after you install the drivers there
-will occur some conflicts between the Bluetooth stacks. (At least that is
-what happend on my machine : I wasn't able to use the Bluesoleil stack and
-the WINDCOMM one in the same time).
-
-If you have two different machines and your configuration files are good
-you can use the same scenario presented on the begining of this section.
-
-Another way to test the plugin functionality is to create your own
-application which will use the GNUnet framework with the Bluetooth
-transport service.
-
-@node The implementation of the Bluetooth transport plugin
-@subsection The implementation of the Bluetooth transport plugin
-@c %**end of header
-
-This page describes the implementation of the Bluetooth transport plugin.
-
-First I want to remind you that the Bluetooth transport plugin uses
-virtually the same code as the WLAN plugin and only the helper binary is
-different. Also the scope of the helper binary from the Bluetooth
-transport plugin is the same as the one used for the wlan transport
-plugin: it acceses the interface and then it forwards traffic in both
-directions between the Bluetooth interface and stdin/stdout of the
-process involved.
-
-The Bluetooth plugin transport could be used both on Linux and Windows
-platforms.
-
-@itemize @bullet
-@item Linux functionality
-@item Windows functionality
-@item Pending Features
-@end itemize
-
-
-
-@menu
-* Linux functionality::
-* THE INITIALIZATION::
-* THE LOOP::
-* Details about the broadcast implementation::
-* Windows functionality::
-* Pending features::
-@end menu
-
-@node Linux functionality
-@subsubsection Linux functionality
-@c %**end of header
-
-In order to implement the plugin functionality on Linux I used the BlueZ
-stack. For the communication with the other devices I used the RFCOMM
-protocol. Also I used the HCI protocol to gain some control over the
-device. The helper binary takes a single argument (the name of the
-Bluetooth interface) and is separated in two stages:
-
-@c %** 'THE INITIALIZATION' should be in bigger letters or stand out, not
-@c %** starting a new section?
-@node THE INITIALIZATION
-@subsubsection THE INITIALIZATION
-
-@itemize @bullet
-@item first, it checks if we have root privilegies
-(@emph{Remember that we need to have root privilegies in order to be able
-to bring the interface up if it is down or to change its state.}).
-
-@item second, it verifies if the interface with the given name exists.
-
-@strong{If the interface with that name exists and it is a Bluetooth
-interface:}
-
-@item it creates a RFCOMM socket which will be used for listening and call
-the @emph{open_device} method
-
-On the @emph{open_device} method:
-@itemize @bullet
-@item creates a HCI socket used to send control events to the the device
-@item searches for the device ID using the interface name
-@item saves the device MAC address
-@item checks if the interface is down and tries to bring it UP
-@item checks if the interface is in discoverable mode and tries to make it
-discoverable
-@item closes the HCI socket and binds the RFCOMM one
-@item switches the RFCOMM socket in listening mode
-@item registers the SDP service (the service will be used by the other
-devices to get the port on which this device is listening on)
-@end itemize
-
-@item drops the root privilegies
-
-@strong{If the interface is not a Bluetooth interface the helper exits
-with a suitable error}
-@end itemize
-
-@c %** Same as for @node entry above
-@node THE LOOP
-@subsubsection THE LOOP
-
-The helper binary uses a list where it saves all the connected neighbour
-devices (@emph{neighbours.devices}) and two buffers (@emph{write_pout} and
-@emph{write_std}). The first message which is send is a control message
-with the device's MAC address in order to announce the peer presence to
-the neighbours. Here are a short description of what happens in the main
-loop:
-
-@itemize @bullet
-@item Every time when it receives something from the STDIN it processes
-the data and saves the message in the first buffer (@emph{write_pout}).
-When it has something in the buffer, it gets the destination address from
-the buffer, searches the destination address in the list (if there is no
-connection with that device, it creates a new one and saves it to the
-list) and sends the message.
-@item Every time when it receives something on the listening socket it
-accepts the connection and saves the socket on a list with the reading
-sockets. @item Every time when it receives something from a reading
-socket it parses the message, verifies the CRC and saves it in the
-@emph{write_std} buffer in order to be sent later to the STDOUT.
-@end itemize
-
-So in the main loop we use the select function to wait until one of the
-file descriptor saved in one of the two file descriptors sets used is
-ready to use. The first set (@emph{rfds}) represents the reading set and
-it could contain the list with the reading sockets, the STDIN file
-descriptor or the listening socket. The second set (@emph{wfds}) is the
-writing set and it could contain the sending socket or the STDOUT file
-descriptor. After the select function returns, we check which file
-descriptor is ready to use and we do what is supposed to do on that kind
-of event. @emph{For example:} if it is the listening socket then we
-accept a new connection and save the socket in the reading list; if it is
-the STDOUT file descriptor, then we write to STDOUT the message from the
-@emph{write_std} buffer.
-
-To find out on which port a device is listening on we connect to the local
-SDP server and searche the registered service for that device.
-
-@emph{You should be aware of the fact that if the device fails to connect
-to another one when trying to send a message it will attempt one more
-time. If it fails again, then it skips the message.}
-@emph{Also you should know that the transport Bluetooth plugin has
-support for @strong{broadcast messages}.}
-
-@node Details about the broadcast implementation
-@subsubsection Details about the broadcast implementation
-@c %**end of header
-
-First I want to point out that the broadcast functionality for the CONTROL
-messages is not implemented in a conventional way. Since the inquiry scan
-time is too big and it will take some time to send a message to all the
-discoverable devices I decided to tackle the problem in a different way.
-Here is how I did it:
-
-@itemize @bullet
-@item If it is the first time when I have to broadcast a message I make an
-inquiry scan and save all the devices' addresses to a vector.
-@item After the inquiry scan ends I take the first address from the list
-and I try to connect to it. If it fails, I try to connect to the next one.
-If it succeeds, I save the socket to a list and send the message to the
-device.
-@item When I have to broadcast another message, first I search on the list
-for a new device which I'm not connected to. If there is no new device on
-the list I go to the beginning of the list and send the message to the
-old devices. After 5 cycles I make a new inquiry scan to check out if
-there are new discoverable devices and save them to the list. If there
-are no new discoverable devices I reset the cycling counter and go again
-through the old list and send messages to the devices saved in it.
-@end itemize
-
-@strong{Therefore}:
-
-@itemize @bullet
-@item every time when I have a broadcast message I look up on the list
-for a new device and send the message to it
-@item if I reached the end of the list for 5 times and I'm connected to
-all the devices from the list I make a new inquiry scan.
-@emph{The number of the list's cycles after an inquiry scan could be
-increased by redefining the MAX_LOOPS variable}
-@item when there are no new devices I send messages to the old ones.
-@end itemize
-
-Doing so, the broadcast control messages will reach the devices but with
-delay.
-
-@emph{NOTICE:} When I have to send a message to a certain device first I
-check on the broadcast list to see if we are connected to that device. If
-not we try to connect to it and in case of success we save the address and
-the socket on the list. If we are already connected to that device we
-simply use the socket.
-
-@node Windows functionality
-@subsubsection Windows functionality
-@c %**end of header
-
-For Windows I decided to use the Microsoft Bluetooth stack which has the
-advantage of coming standard from Windows XP SP2. The main disadvantage is
-that it only supports the RFCOMM protocol so we will not be able to have
-a low level control over the Bluetooth device. Therefore it is the user
-responsability to check if the device is up and in the discoverable mode.
-Also there are no tools which could be used for debugging in order to read
-the data coming from and going to a Bluetooth device, which obviously
-hindered my work. Another thing that slowed down the implementation of the
-plugin (besides that I wasn't too accomodated with the win32 API) was that
-there were some bugs on MinGW regarding the Bluetooth. Now they are solved
-but you should keep in mind that you should have the latest updates
-(especially the @emph{ws2bth} header).
-
-Besides the fact that it uses the Windows Sockets, the Windows
-implemenation follows the same principles as the Linux one:
-
-@itemize @bullet
-@item It has a initalization part where it initializes the
-Windows Sockets, creates a RFCOMM socket which will be binded and switched
-to the listening mode and registers a SDP service. In the Microsoft
-Bluetooth API there are two ways to work with the SDP:
-@itemize @bullet
-@item an easy way which works with very simple service records
-@item a hard way which is useful when you need to update or to delete the
-record
-@end itemize
-@end itemize
-
-Since I only needed the SDP service to find out on which port the device
-is listening on and that did not change, I decided to use the easy way.
-In order to register the service I used the @emph{WSASetService} function
-and I generated the @emph{Universally Unique Identifier} with the
-@emph{guidgen.exe} Windows's tool.
-
-In the loop section the only difference from the Linux implementation is
-that I used the GNUNET_NETWORK library for functions like @emph{accept},
-@emph{bind}, @emph{connect} or @emph{select}. I decided to use the
-GNUNET_NETWORK library because I also needed to interact with the STDIN
-and STDOUT handles and on Windows the select function is only defined for
-sockets, and it will not work for arbitrary file handles.
-
-Another difference between Linux and Windows implementation is that in
-Linux, the Bluetooth address is represented in 48 bits while in Windows is
-represented in 64 bits. Therefore I had to do some changes on
-@emph{plugin_transport_wlan} header.
-
-Also, currently on Windows the Bluetooth plugin doesn't have support for
-broadcast messages. When it receives a broadcast message it will skip it.
-
-@node Pending features
-@subsubsection Pending features
-@c %**end of header
-
-@itemize @bullet
-@item Implement the broadcast functionality on Windows @emph{(currently
-working on)}
-@item Implement a testcase for the helper :@ @emph{The testcase
-consists of a program which emaluates the plugin and uses the helper. It
-will simulate connections, disconnections and data transfers.}
-@end itemize
-
-If you have a new idea about a feature of the plugin or suggestions about
-how I could improve the implementation you are welcome to comment or to
-contact me.
-
-@node WLAN plugin
-@section WLAN plugin
-@c %**end of header
-
-This section documents how the wlan transport plugin works. Parts which
-are not implemented yet or could be better implemented are described at
-the end.
-
-@cindex ats subsystem
-@node The ATS Subsystem
-@section The ATS Subsystem
-@c %**end of header
-
-ATS stands for "automatic transport selection", and the function of ATS in
-GNUnet is to decide on which address (and thus transport plugin) should
-be used for two peers to communicate, and what bandwidth limits should be
-imposed on such an individual connection. To help ATS make an informed
-decision, higher-level services inform the ATS service about their
-requirements and the quality of the service rendered. The ATS service
-also interacts with the transport service to be appraised of working
-addresses and to communicate its resource allocation decisions. Finally,
-the ATS service's operation can be observed using a monitoring API.
-
-The main logic of the ATS service only collects the available addresses,
-their performance characteristics and the applications requirements, but
-does not make the actual allocation decision. This last critical step is
-left to an ATS plugin, as we have implemented (currently three) different
-allocation strategies which differ significantly in their performance and
-maturity, and it is still unclear if any particular plugin is generally
-superior.
-
-@cindex core subsystem
-@cindex CORE subsystem
-@node GNUnet's CORE Subsystem
-@section GNUnet's CORE Subsystem
-@c %**end of header
-
-The CORE subsystem in GNUnet is responsible for securing link-layer
-communications between nodes in the GNUnet overlay network. CORE builds
-on the TRANSPORT subsystem which provides for the actual, insecure,
-unreliable link-layer communication (for example, via UDP or WLAN), and
-then adds fundamental security to the connections:
-
-@itemize @bullet
-@item confidentiality with so-called perfect forward secrecy; we use
-ECDHE@footnote{@uref{http://en.wikipedia.org/wiki/Elliptic_curve_
-Diffie%E2%80%93Hellman, Elliptic-curve Diffie---Hellman}}
-powered by Curve25519
-@footnote{@uref{http://cr.yp.to/ecdh.html, Curve25519}} for the key
-exchange and then use symmetric encryption, encrypting with both AES-256
-@footnote{@uref{http://en.wikipedia.org/wiki/Rijndael, AES-256}} and
-Twofish @footnote{@uref{http://en.wikipedia.org/wiki/Twofish, Twofish}}
-@item @uref{http://en.wikipedia.org/wiki/Authentication, authentication}
-is achieved by signing the ephemeral keys using Ed25519
-@footnote{@uref{http://ed25519.cr.yp.to/, Ed25519}}, a deterministic
-variant of ECDSA
-@footnote{@uref{http://en.wikipedia.org/wiki/ECDSA, ECDSA}}
-@item integrity protection (using SHA-512
-@footnote{@uref{http://en.wikipedia.org/wiki/SHA-2, SHA-512}} to do
-encrypt-then-MAC
-@footnote{@uref{http://en.wikipedia.org/wiki/Authenticated_encryption,
-encrypt-then-MAC}})
-@item Replay
-@footnote{@uref{http://en.wikipedia.org/wiki/Replay_attack, replay}}
-protection (using nonces, timestamps, challenge-response,
-message counters and ephemeral keys)
-@item liveness (keep-alive messages, timeout)
-@end itemize
-
-@menu
-* Limitations::
-* When is a peer "connected"?::
-* libgnunetcore::
-* The CORE Client-Service Protocol::
-* The CORE Peer-to-Peer Protocol::
-@end menu
-
-@cindex core subsystem limitations
-@node Limitations
-@subsection Limitations
-@c %**end of header
-
-CORE does not perform
-@uref{http://en.wikipedia.org/wiki/Routing, routing}; using CORE it is
-only possible to communicate with peers that happen to already be
-"directly" connected with each other. CORE also does not have an
-API to allow applications to establish such "direct" connections --- for
-this, applications can ask TRANSPORT, but TRANSPORT might not be able to
-establish a "direct" connection. The TOPOLOGY subsystem is responsible for
-trying to keep a few "direct" connections open at all times. Applications
-that need to talk to particular peers should use the CADET subsystem, as
-it can establish arbitrary "indirect" connections.
-
-Because CORE does not perform routing, CORE must only be used directly by
-applications that either perform their own routing logic (such as
-anonymous file-sharing) or that do not require routing, for example
-because they are based on flooding the network. CORE communication is
-unreliable and delivery is possibly out-of-order. Applications that
-require reliable communication should use the CADET service. Each
-application can only queue one message per target peer with the CORE
-service at any time; messages cannot be larger than approximately
-63 kilobytes. If messages are small, CORE may group multiple messages
-(possibly from different applications) prior to encryption. If permitted
-by the application (using the @uref{http://baus.net/on-tcp_cork/, cork}
-option), CORE may delay transmissions to facilitate grouping of multiple
-small messages. If cork is not enabled, CORE will transmit the message as
-soon as TRANSPORT allows it (TRANSPORT is responsible for limiting
-bandwidth and congestion control). CORE does not allow flow control;
-applications are expected to process messages at line-speed. If flow
-control is needed, applications should use the CADET service.
-
-@cindex when is a peer connected
-@node When is a peer "connected"?
-@subsection When is a peer "connected"?
-@c %**end of header
-
-In addition to the security features mentioned above, CORE also provides
-one additional key feature to applications using it, and that is a
-limited form of protocol-compatibility checking. CORE distinguishes
-between TRANSPORT-level connections (which enable communication with other
-peers) and application-level connections. Applications using the CORE API
-will (typically) learn about application-level connections from CORE, and
-not about TRANSPORT-level connections. When a typical application uses
-CORE, it will specify a set of message types
-(from @code{gnunet_protocols.h}) that it understands. CORE will then
-notify the application about connections it has with other peers if and
-only if those applications registered an intersecting set of message
-types with their CORE service. Thus, it is quite possible that CORE only
-exposes a subset of the established direct connections to a particular
-application --- and different applications running above CORE might see
-different sets of connections at the same time.
-
-A special case are applications that do not register a handler for any
-message type.
-CORE assumes that these applications merely want to monitor connections
-(or "all" messages via other callbacks) and will notify those applications
-about all connections. This is used, for example, by the
-@code{gnunet-core} command-line tool to display the active connections.
-Note that it is also possible that the TRANSPORT service has more active
-connections than the CORE service, as the CORE service first has to
-perform a key exchange with connecting peers before exchanging information
-about supported message types and notifying applications about the new
-connection.
-
-@cindex libgnunetcore
-@node libgnunetcore
-@subsection libgnunetcore
-@c %**end of header
-
-The CORE API (defined in @file{gnunet_core_service.h}) is the basic
-messaging API used by P2P applications built using GNUnet. It provides
-applications the ability to send and receive encrypted messages to the
-peer's "directly" connected neighbours.
-
-As CORE connections are generally "direct" connections,@ applications must
-not assume that they can connect to arbitrary peers this way, as "direct"
-connections may not always be possible. Applications using CORE are
-notified about which peers are connected. Creating new "direct"
-connections must be done using the TRANSPORT API.
-
-The CORE API provides unreliable, out-of-order delivery. While the
-implementation tries to ensure timely, in-order delivery, both message
-losses and reordering are not detected and must be tolerated by the
-application. Most important, the core will NOT perform retransmission if
-messages could not be delivered.
-
-Note that CORE allows applications to queue one message per connected
-peer. The rate at which each connection operates is influenced by the
-preferences expressed by local application as well as restrictions
-imposed by the other peer. Local applications can express their
-preferences for particular connections using the "performance" API of the
-ATS service.
-
-Applications that require more sophisticated transmission capabilities
-such as TCP-like behavior, or if you intend to send messages to arbitrary
-remote peers, should use the CADET API.
-
-The typical use of the CORE API is to connect to the CORE service using
-@code{GNUNET_CORE_connect}, process events from the CORE service (such as
-peers connecting, peers disconnecting and incoming messages) and send
-messages to connected peers using
-@code{GNUNET_CORE_notify_transmit_ready}. Note that applications must
-cancel pending transmission requests if they receive a disconnect event
-for a peer that had a transmission pending; furthermore, queueing more
-than one transmission request per peer per application using the
-service is not permitted.
-
-The CORE API also allows applications to monitor all communications of the
-peer prior to encryption (for outgoing messages) or after decryption (for
-incoming messages). This can be useful for debugging, diagnostics or to
-establish the presence of cover traffic (for anonymity). As monitoring
-applications are often not interested in the payload, the monitoring
-callbacks can be configured to only provide the message headers (including
-the message type and size) instead of copying the full data stream to the
-monitoring client.
-
-The init callback of the @code{GNUNET_CORE_connect} function is called
-with the hash of the public key of the peer. This public key is used to
-identify the peer globally in the GNUnet network. Applications are
-encouraged to check that the provided hash matches the hash that they are
-using (as theoretically the application may be using a different
-configuration file with a different private key, which would result in
-hard to find bugs).
-
-As with most service APIs, the CORE API isolates applications from crashes
-of the CORE service. If the CORE service crashes, the application will see
-disconnect events for all existing connections. Once the connections are
-re-established, the applications will be receive matching connect events.
-
-@cindex core clinet-service protocol
-@node The CORE Client-Service Protocol
-@subsection The CORE Client-Service Protocol
-@c %**end of header
-
-This section describes the protocol between an application using the CORE
-service (the client) and the CORE service process itself.
-
-
-@menu
-* Setup2::
-* Notifications::
-* Sending::
-@end menu
-
-@node Setup2
-@subsubsection Setup2
-@c %**end of header
-
-When a client connects to the CORE service, it first sends a
-@code{InitMessage} which specifies options for the connection and a set of
-message type values which are supported by the application. The options
-bitmask specifies which events the client would like to be notified about.
-The options include:
-
-@table @asis
-@item GNUNET_CORE_OPTION_NOTHING No notifications
-@item GNUNET_CORE_OPTION_STATUS_CHANGE Peers connecting and disconnecting
-@item GNUNET_CORE_OPTION_FULL_INBOUND All inbound messages (after
-decryption) with full payload
-@item GNUNET_CORE_OPTION_HDR_INBOUND Just the @code{MessageHeader}
-of all inbound messages
-@item GNUNET_CORE_OPTION_FULL_OUTBOUND All outbound
-messages (prior to encryption) with full payload
-@item GNUNET_CORE_OPTION_HDR_OUTBOUND Just the @code{MessageHeader} of all
-outbound messages
-@end table
-
-Typical applications will only monitor for connection status changes.
-
-The CORE service responds to the @code{InitMessage} with an
-@code{InitReplyMessage} which contains the peer's identity. Afterwards,
-both CORE and the client can send messages.
-
-@node Notifications
-@subsubsection Notifications
-@c %**end of header
-
-The CORE will send @code{ConnectNotifyMessage}s and
-@code{DisconnectNotifyMessage}s whenever peers connect or disconnect from
-the CORE (assuming their type maps overlap with the message types
-registered by the client). When the CORE receives a message that matches
-the set of message types specified during the @code{InitMessage} (or if
-monitoring is enabled in for inbound messages in the options), it sends a
-@code{NotifyTrafficMessage} with the peer identity of the sender and the
-decrypted payload. The same message format (except with
-@code{GNUNET_MESSAGE_TYPE_CORE_NOTIFY_OUTBOUND} for the message type) is
-used to notify clients monitoring outbound messages; here, the peer
-identity given is that of the receiver.
-
-@node Sending
-@subsubsection Sending
-@c %**end of header
-
-When a client wants to transmit a message, it first requests a
-transmission slot by sending a @code{SendMessageRequest} which specifies
-the priority, deadline and size of the message. Note that these values
-may be ignored by CORE. When CORE is ready for the message, it answers
-with a @code{SendMessageReady} response. The client can then transmit the
-payload with a @code{SendMessage} message. Note that the actual message
-size in the @code{SendMessage} is allowed to be smaller than the size in
-the original request. A client may at any time send a fresh
-@code{SendMessageRequest}, which then superceeds the previous
-@code{SendMessageRequest}, which is then no longer valid. The client can
-tell which @code{SendMessageRequest} the CORE service's
-@code{SendMessageReady} message is for as all of these messages contain a
-"unique" request ID (based on a counter incremented by the client
-for each request).
-
-@node The CORE Peer-to-Peer Protocol
-@subsection The CORE Peer-to-Peer Protocol
-@c %**end of header
-
-
-@menu
-* Creating the EphemeralKeyMessage::
-* Establishing a connection::
-* Encryption and Decryption::
-* Type maps::
-@end menu
-
-@cindex EphemeralKeyMessage creation
-@node Creating the EphemeralKeyMessage
-@subsubsection Creating the EphemeralKeyMessage
-@c %**end of header
-
-When the CORE service starts, each peer creates a fresh ephemeral (ECC)
-public-private key pair and signs the corresponding
-@code{EphemeralKeyMessage} with its long-term key (which we usually call
-the peer's identity; the hash of the public long term key is what results
-in a @code{struct GNUNET_PeerIdentity} in all GNUnet APIs. The ephemeral
-key is ONLY used for an ECDHE@footnote{@uref{http://en.wikipedia.org/wiki/
-Elliptic_curve_Diffie%E2%80%93Hellman, Elliptic-curve Diffie---Hellman}}
-exchange by the CORE service to establish symmetric session keys. A peer
-will use the same @code{EphemeralKeyMessage} for all peers for
-@code{REKEY_FREQUENCY}, which is usually 12 hours. After that time, it
-will create a fresh ephemeral key (forgetting the old one) and broadcast
-the new @code{EphemeralKeyMessage} to all connected peers, resulting in
-fresh symmetric session keys. Note that peers independently decide on
-when to discard ephemeral keys; it is not a protocol violation to discard
-keys more often. Ephemeral keys are also never stored to disk; restarting
-a peer will thus always create a fresh ephemeral key. The use of ephemeral
-keys is what provides @uref{http://en.wikipedia.org/wiki/Forward_secrecy,
-forward secrecy}.
-
-Just before transmission, the @code{EphemeralKeyMessage} is patched to
-reflect the current sender_status, which specifies the current state of
-the connection from the point of view of the sender. The possible values
-are:
-
-@itemize @bullet
-@item @code{KX_STATE_DOWN} Initial value, never used on the network
-@item @code{KX_STATE_KEY_SENT} We sent our ephemeral key, do not know the
-key of the other peer
-@item @code{KX_STATE_KEY_RECEIVED} This peer has received a valid
-ephemeral key of the other peer, but we are waiting for the other peer to
-confirm it's authenticity (ability to decode) via challenge-response.
-@item @code{KX_STATE_UP} The connection is fully up from the point of
-view of the sender (now performing keep-alives)
-@item @code{KX_STATE_REKEY_SENT} The sender has initiated a rekeying
-operation; the other peer has so far failed to confirm a working
-connection using the new ephemeral key
-@end itemize
-
-@node Establishing a connection
-@subsubsection Establishing a connection
-@c %**end of header
-
-Peers begin their interaction by sending a @code{EphemeralKeyMessage} to
-the other peer once the TRANSPORT service notifies the CORE service about
-the connection.
-A peer receiving an @code{EphemeralKeyMessage} with a status
-indicating that the sender does not have the receiver's ephemeral key, the
-receiver's @code{EphemeralKeyMessage} is sent in response.
-Additionally, if the receiver has not yet confirmed the authenticity of
-the sender, it also sends an (encrypted)@code{PingMessage} with a
-challenge (and the identity of the target) to the other peer. Peers
-receiving a @code{PingMessage} respond with an (encrypted)
-@code{PongMessage} which includes the challenge. Peers receiving a
-@code{PongMessage} check the challenge, and if it matches set the
-connection to @code{KX_STATE_UP}.
-
-@node Encryption and Decryption
-@subsubsection Encryption and Decryption
-@c %**end of header
-
-All functions related to the key exchange and encryption/decryption of
-messages can be found in @file{gnunet-service-core_kx.c} (except for the
-cryptographic primitives, which are in @file{util/crypto*.c}).
-Given the key material from ECDHE, a Key derivation function
-@footnote{@uref{https://en.wikipedia.org/wiki/Key_derivation_function, Key
-derivation function}} is used to derive two pairs of encryption and
-decryption keys for AES-256 and TwoFish, as well as initialization vectors
-and authentication keys (for HMAC@footnote{@uref{https://en.wikipedia.org/
-wiki/HMAC, HMAC}}). The HMAC is computed over the encrypted payload.
-Encrypted messages include an iv_seed and the HMAC in the header.
-
-Each encrypted message in the CORE service includes a sequence number and
-a timestamp in the encrypted payload. The CORE service remembers the
-largest observed sequence number and a bit-mask which represents which of
-the previous 32 sequence numbers were already used.
-Messages with sequence numbers lower than the largest observed sequence
-number minus 32 are discarded. Messages with a timestamp that is less
-than @code{REKEY_TOLERANCE} off (5 minutes) are also discarded. This of
-course means that system clocks need to be reasonably synchronized for
-peers to be able to communicate. Additionally, as the ephemeral key
-changes every 12 hours, a peer would not even be able to decrypt messages
-older than 12 hours.
-
-@node Type maps
-@subsubsection Type maps
-@c %**end of header
-
-Once an encrypted connection has been established, peers begin to exchange
-type maps. Type maps are used to allow the CORE service to determine which
-(encrypted) connections should be shown to which applications. A type map
-is an array of 65536 bits representing the different types of messages
-understood by applications using the CORE service. Each CORE service
-maintains this map, simply by setting the respective bit for each message
-type supported by any of the applications using the CORE service. Note
-that bits for message types embedded in higher-level protocols (such as
-MESH) will not be included in these type maps.
-
-Typically, the type map of a peer will be sparse. Thus, the CORE service
-attempts to compress its type map using @code{gzip}-style compression
-("deflate") prior to transmission. However, if the compression fails to
-compact the map, the map may also be transmitted without compression
-(resulting in @code{GNUNET_MESSAGE_TYPE_CORE_COMPRESSED_TYPE_MAP} or
-@code{GNUNET_MESSAGE_TYPE_CORE_BINARY_TYPE_MAP} messages respectively).
-Upon receiving a type map, the respective CORE service notifies
-applications about the connection to the other peer if they support any
-message type indicated in the type map (or no message type at all).
-If the CORE service experience a connect or disconnect event from an
-application, it updates its type map (setting or unsetting the respective
-bits) and notifies its neighbours about the change.
-The CORE services of the neighbours then in turn generate connect and
-disconnect events for the peer that sent the type map for their respective
-applications. As CORE messages may be lost, the CORE service confirms
-receiving a type map by sending back a
-@code{GNUNET_MESSAGE_TYPE_CORE_CONFIRM_TYPE_MAP}. If such a confirmation
-(with the correct hash of the type map) is not received, the sender will
-retransmit the type map (with exponential back-off).
-
-@cindex cadet subsystem
-@cindex CADET
-@node GNUnet's CADET subsystem
-@section GNUnet's CADET subsystem
-
-The CADET subsystem in GNUnet is responsible for secure end-to-end
-communications between nodes in the GNUnet overlay network. CADET builds
-on the CORE subsystem which provides for the link-layer communication and
-then adds routing, forwarding and additional security to the connections.
-CADET offers the same cryptographic services as CORE, but on an
-end-to-end level. This is done so peers retransmitting traffic on behalf
-of other peers cannot access the payload data.
-
-@itemize @bullet
-@item CADET provides confidentiality with so-called perfect forward
-secrecy; we use ECDHE powered by Curve25519 for the key exchange and then
-use symmetric encryption, encrypting with both AES-256 and Twofish
-@item authentication is achieved by signing the ephemeral keys using
-Ed25519, a deterministic variant of ECDSA
-@item integrity protection (using SHA-512 to do encrypt-then-MAC, although
-only 256 bits are sent to reduce overhead)
-@item replay protection (using nonces, timestamps, challenge-response,
-message counters and ephemeral keys)
-@item liveness (keep-alive messages, timeout)
-@end itemize
-
-Additional to the CORE-like security benefits, CADET offers other
-properties that make it a more universal service than CORE.
-
-@itemize @bullet
-@item CADET can establish channels to arbitrary peers in GNUnet. If a
-peer is not immediately reachable, CADET will find a path through the
-network and ask other peers to retransmit the traffic on its behalf.
-@item CADET offers (optional) reliability mechanisms. In a reliable
-channel traffic is guaranteed to arrive complete, unchanged and in-order.
-@item CADET takes care of flow and congestion control mechanisms, not
-allowing the sender to send more traffic than the receiver or the network
-are able to process.
-@end itemize
-
-@menu
-* libgnunetcadet::
-@end menu
-
-@cindex libgnunetcadet
-@node libgnunetcadet
-@subsection libgnunetcadet
-
-
-The CADET API (defined in @file{gnunet_cadet_service.h}) is the
-messaging API used by P2P applications built using GNUnet.
-It provides applications the ability to send and receive encrypted
-messages to any peer participating in GNUnet.
-The API is heavily base on the CORE API.
-
-CADET delivers messages to other peers in "channels".
-A channel is a permanent connection defined by a destination peer
-(identified by its public key) and a port number.
-Internally, CADET tunnels all channels towards a destiantion peer
-using one session key and relays the data on multiple "connections",
-independent from the channels.
-
-Each channel has optional paramenters, the most important being the
-reliability flag.
-Should a message get lost on TRANSPORT/CORE level, if a channel is
-created with as reliable, CADET will retransmit the lost message and
-deliver it in order to the destination application.
-
-To communicate with other peers using CADET, it is necessary to first
-connect to the service using @code{GNUNET_CADET_connect}.
-This function takes several parameters in form of callbacks, to allow the
-client to react to various events, like incoming channels or channels that
-terminate, as well as specify a list of ports the client wishes to listen
-to (at the moment it is not possible to start listening on further ports
-once connected, but nothing prevents a client to connect several times to
-CADET, even do one connection per listening port).
-The function returns a handle which has to be used for any further
-interaction with the service.
-
-To connect to a remote peer a client has to call the
-@code{GNUNET_CADET_channel_create} function. The most important parameters
-given are the remote peer's identity (it public key) and a port, which
-specifies which application on the remote peer to connect to, similar to
-TCP/UDP ports. CADET will then find the peer in the GNUnet network and
-establish the proper low-level connections and do the necessary key
-exchanges to assure and authenticated, secure and verified communication.
-Similar to @code{GNUNET_CADET_connect},@code{GNUNET_CADET_create_channel}
-returns a handle to interact with the created channel.
-
-For every message the client wants to send to the remote application,
-@code{GNUNET_CADET_notify_transmit_ready} must be called, indicating the
-channel on which the message should be sent and the size of the message
-(but not the message itself!). Once CADET is ready to send the message,
-the provided callback will fire, and the message contents are provided to
-this callback.
-
-Please note the CADET does not provide an explicit notification of when a
-channel is connected. In loosely connected networks, like big wireless
-mesh networks, this can take several seconds, even minutes in the worst
-case. To be alerted when a channel is online, a client can call
-@code{GNUNET_CADET_notify_transmit_ready} immediately after
-@code{GNUNET_CADET_create_channel}. When the callback is activated, it
-means that the channel is online. The callback can give 0 bytes to CADET
-if no message is to be sent, this is ok.
-
-If a transmission was requested but before the callback fires it is no
-longer needed, it can be cancelled with
-@code{GNUNET_CADET_notify_transmit_ready_cancel}, which uses the handle
-given back by @code{GNUNET_CADET_notify_transmit_ready}.
-As in the case of CORE, only one message can be requested at a time: a
-client must not call @code{GNUNET_CADET_notify_transmit_ready} again until
-the callback is called or the request is cancelled.
-
-When a channel is no longer needed, a client can call
-@code{GNUNET_CADET_channel_destroy} to get rid of it.
-Note that CADET will try to transmit all pending traffic before notifying
-the remote peer of the destruction of the channel, including
-retransmitting lost messages if the channel was reliable.
-
-Incoming channels, channels being closed by the remote peer, and traffic
-on any incoming or outgoing channels are given to the client when CADET
-executes the callbacks given to it at the time of
-@code{GNUNET_CADET_connect}.
-
-Finally, when an application no longer wants to use CADET, it should call
-@code{GNUNET_CADET_disconnect}, but first all channels and pending
-transmissions must be closed (otherwise CADET will complain).
-
-@cindex nse subsystem
-@cindex NSE
-@node GNUnet's NSE subsystem
-@section GNUnet's NSE subsystem
-
-
-NSE stands for @dfn{Network Size Estimation}. The NSE subsystem provides
-other subsystems and users with a rough estimate of the number of peers
-currently participating in the GNUnet overlay.
-The computed value is not a precise number as producing a precise number
-in a decentralized, efficient and secure way is impossible.
-While NSE's estimate is inherently imprecise, NSE also gives the expected
-range. For a peer that has been running in a stable network for a
-while, the real network size will typically (99.7% of the time) be in the
-range of [2/3 estimate, 3/2 estimate]. We will now give an overview of the
-algorithm used to calculate the estimate;
-all of the details can be found in this technical report.
-
-@c FIXME: link to the report.
-
-@menu
-* Motivation::
-* Principle::
-* libgnunetnse::
-* The NSE Client-Service Protocol::
-* The NSE Peer-to-Peer Protocol::
-@end menu
-
-@node Motivation
-@subsection Motivation
-
-
-Some subsytems, like DHT, need to know the size of the GNUnet network to
-optimize some parameters of their own protocol. The decentralized nature
-of GNUnet makes efficient and securely counting the exact number of peers
-infeasable. Although there are several decentralized algorithms to count
-the number of peers in a system, so far there is none to do so securely.
-Other protocols may allow any malicious peer to manipulate the final
-result or to take advantage of the system to perform
-@dfn{Denial of Service} (DoS) attacks against the network.
-GNUnet's NSE protocol avoids these drawbacks.
-
-
-
-@menu
-* Security::
-@end menu
-
-@cindex NSE security
-@cindex nse security
-@node Security
-@subsubsection Security
-
-
-The NSE subsystem is designed to be resilient against these attacks.
-It uses @uref{http://en.wikipedia.org/wiki/Proof-of-work_system, proofs
-of work} to prevent one peer from impersonating a large number of
-participants, which would otherwise allow an adversary to artifically
-inflate the estimate.
-The DoS protection comes from the time-based nature of the protocol:
-the estimates are calculated periodically and out-of-time traffic is
-either ignored or stored for later retransmission by benign peers.
-In particular, peers cannot trigger global network communication at will.
-
-@cindex NSE principle
-@cindex nse principle
-@node Principle
-@subsection Principle
-
-
-The algorithm calculates the estimate by finding the globally closest
-peer ID to a random, time-based value.
-
-The idea is that the closer the ID is to the random value, the more
-"densely packed" the ID space is, and therefore, more peers are in the
-network.
-
-
-
-@menu
-* Example::
-* Algorithm::
-* Target value::
-* Timing::
-* Controlled Flooding::
-* Calculating the estimate::
-@end menu
-
-@node Example
-@subsubsection Example
-
-
-Suppose all peers have IDs between 0 and 100 (our ID space), and the
-random value is 42.
-If the closest peer has the ID 70 we can imagine that the average
-"distance" between peers is around 30 and therefore the are around 3
-peers in the whole ID space. On the other hand, if the closest peer has
-the ID 44, we can imagine that the space is rather packed with peers,
-maybe as much as 50 of them.
-Naturally, we could have been rather unlucky, and there is only one peer
-and happens to have the ID 44. Thus, the current estimate is calculated
-as the average over multiple rounds, and not just a single sample.
-
-@node Algorithm
-@subsubsection Algorithm
-
-
-Given that example, one can imagine that the job of the subsystem is to
-efficiently communicate the ID of the closest peer to the target value
-to all the other peers, who will calculate the estimate from it.
-
-@node Target value
-@subsubsection Target value
-
-@c %**end of header
-
-The target value itself is generated by hashing the current time, rounded
-down to an agreed value. If the rounding amount is 1h (default) and the
-time is 12:34:56, the time to hash would be 12:00:00. The process is
-repeated each rouning amount (in this example would be every hour).
-Every repetition is called a round.
-
-@node Timing
-@subsubsection Timing
-@c %**end of header
-
-The NSE subsystem has some timing control to avoid everybody broadcasting
-its ID all at one. Once each peer has the target random value, it
-compares its own ID to the target and calculates the hypothetical size of
-the network if that peer were to be the closest.
-Then it compares the hypothetical size with the estimate from the previous
-rounds. For each value there is an assiciated point in the period,
-let's call it "broadcast time". If its own hypothetical estimate
-is the same as the previous global estimate, its "broadcast time" will be
-in the middle of the round. If its bigger it will be earlier and if its
-smaller (the most likely case) it will be later. This ensures that the
-peers closests to the target value start broadcasting their ID the first.
-
-@node Controlled Flooding
-@subsubsection Controlled Flooding
-
-@c %**end of header
-
-When a peer receives a value, first it verifies that it is closer than the
-closest value it had so far, otherwise it answers the incoming message
-with a message containing the better value. Then it checks a proof of
-work that must be included in the incoming message, to ensure that the
-other peer's ID is not made up (otherwise a malicious peer could claim to
-have an ID of exactly the target value every round). Once validated, it
-compares the brodcast time of the received value with the current time
-and if it's not too early, sends the received value to its neighbors.
-Otherwise it stores the value until the correct broadcast time comes.
-This prevents unnecessary traffic of sub-optimal values, since a better
-value can come before the broadcast time, rendering the previous one
-obsolete and saving the traffic that would have been used to broadcast it
-to the neighbors.
-
-@node Calculating the estimate
-@subsubsection Calculating the estimate
-
-@c %**end of header
-
-Once the closest ID has been spread across the network each peer gets the
-exact distance betweed this ID and the target value of the round and
-calculates the estimate with a mathematical formula described in the tech
-report. The estimate generated with this method for a single round is not
-very precise. Remember the case of the example, where the only peer is the
-ID 44 and we happen to generate the target value 42, thinking there are
-50 peers in the network. Therefore, the NSE subsystem remembers the last
-64 estimates and calculates an average over them, giving a result of which
-usually has one bit of uncertainty (the real size could be half of the
-estimate or twice as much). Note that the actual network size is
-calculated in powers of two of the raw input, thus one bit of uncertainty
-means a factor of two in the size estimate.
-
-@cindex libgnunetnse
-@node libgnunetnse
-@subsection libgnunetnse
-
-@c %**end of header
-
-The NSE subsystem has the simplest API of all services, with only two
-calls: @code{GNUNET_NSE_connect} and @code{GNUNET_NSE_disconnect}.
-
-The connect call gets a callback function as a parameter and this function
-is called each time the network agrees on an estimate. This usually is
-once per round, with some exceptions: if the closest peer has a late
-local clock and starts spreading his ID after everyone else agreed on a
-value, the callback might be activated twice in a round, the second value
-being always bigger than the first. The default round time is set to
-1 hour.
-
-The disconnect call disconnects from the NSE subsystem and the callback
-is no longer called with new estimates.
-
-
-
-@menu
-* Results::
-* Examples2::
-@end menu
-
-@node Results
-@subsubsection Results
-
-@c %**end of header
-
-The callback provides two values: the average and the
-@uref{http://en.wikipedia.org/wiki/Standard_deviation, standard deviation}
-of the last 64 rounds. The values provided by the callback function are
-logarithmic, this means that the real estimate numbers can be obtained by
-calculating 2 to the power of the given value (2average). From a
-statistics point of view this means that:
-
-@itemize @bullet
-@item 68% of the time the real size is included in the interval
-[(2average-stddev), 2]
-@item 95% of the time the real size is included in the interval
-[(2average-2*stddev, 2^average+2*stddev]
-@item 99.7% of the time the real size is included in the interval
-[(2average-3*stddev, 2average+3*stddev]
-@end itemize
-
-The expected standard variation for 64 rounds in a network of stable size
-is 0.2. Thus, we can say that normally:
-
-@itemize @bullet
-@item 68% of the time the real size is in the range [-13%, +15%]
-@item 95% of the time the real size is in the range [-24%, +32%]
-@item 99.7% of the time the real size is in the range [-34%, +52%]
-@end itemize
-
-As said in the introduction, we can be quite sure that usually the real
-size is between one third and three times the estimate. This can of
-course vary with network conditions.
-Thus, applications may want to also consider the provided standard
-deviation value, not only the average (in particular, if the standard
-veriation is very high, the average maybe meaningless: the network size is
-changing rapidly).
-
-@node Examples2
-@subsubsection Examples2
-
-@c %**end of header
-
-Let's close with a couple examples.
-
-@table @asis
-
-@item Average: 10, std dev: 1 Here the estimate would be
-2^10 = 1024 peers. @footnote{The range in which we can be 95% sure is:
-[2^8, 2^12] = [256, 4096]. We can be very (>99.7%) sure that the network
-is not a hundred peers and absolutely sure that it is not a million peers,
-but somewhere around a thousand.}
-
-@item Average 22, std dev: 0.2 Here the estimate would be
-2^22 = 4 Million peers. @footnote{The range in which we can be 99.7% sure
-is: [2^21.4, 2^22.6] = [2.8M, 6.3M]. We can be sure that the network size
-is around four million, with absolutely way of it being 1 million.}
-
-@end table
-
-To put this in perspective, if someone remembers the LHC Higgs boson
-results, were announced with "5 sigma" and "6 sigma" certainties. In this
-case a 5 sigma minimum would be 2 million and a 6 sigma minimum,
-1.8 million.
-
-@node The NSE Client-Service Protocol
-@subsection The NSE Client-Service Protocol
-
-@c %**end of header
-
-As with the API, the client-service protocol is very simple, only has 2
-different messages, defined in @code{src/nse/nse.h}:
-
-@itemize @bullet
-@item @code{GNUNET_MESSAGE_TYPE_NSE_START}@ This message has no parameters
-and is sent from the client to the service upon connection.
-@item @code{GNUNET_MESSAGE_TYPE_NSE_ESTIMATE}@ This message is sent from
-the service to the client for every new estimate and upon connection.
-Contains a timestamp for the estimate, the average and the standard
-deviation for the respective round.
-@end itemize
-
-When the @code{GNUNET_NSE_disconnect} API call is executed, the client
-simply disconnects from the service, with no message involved.
-
-@node The NSE Peer-to-Peer Protocol
-@subsection The NSE Peer-to-Peer Protocol
-
-@c %**end of header
-
-The NSE subsystem only has one message in the P2P protocol, the
-@code{GNUNET_MESSAGE_TYPE_NSE_P2P_FLOOD} message.
-
-This message key contents are the timestamp to identify the round
-(differences in system clocks may cause some peers to send messages way
-too early or way too late, so the timestamp allows other peers to
-identify such messages easily), the
-@uref{http://en.wikipedia.org/wiki/Proof-of-work_system, proof of work}
-used to make it difficult to mount a
-@uref{http://en.wikipedia.org/wiki/Sybil_attack, Sybil attack}, and the
-public key, which is used to verify the signature on the message.
-
-Every peer stores a message for the previous, current and next round. The
-messages for the previous and current round are given to peers that
-connect to us. The message for the next round is simply stored until our
-system clock advances to the next round. The message for the current round
-is what we are flooding the network with right now.
-At the beginning of each round the peer does the following:
-
-@itemize @bullet
-@item calculates his own distance to the target value
-@item creates, signs and stores the message for the current round (unless
-it has a better message in the "next round" slot which came early in the
-previous round)
-@item calculates, based on the stored round message (own or received) when
-to stard flooding it to its neighbors
-@end itemize
-
-Upon receiving a message the peer checks the validity of the message
-(round, proof of work, signature). The next action depends on the
-contents of the incoming message:
-
-@itemize @bullet
-@item if the message is worse than the current stored message, the peer
-sends the current message back immediately, to stop the other peer from
-spreading suboptimal results
-@item if the message is better than the current stored message, the peer
-stores the new message and calculates the new target time to start
-spreading it to its neighbors (excluding the one the message came from)
-@item if the message is for the previous round, it is compared to the
-message stored in the "previous round slot", which may then be updated
-@item if the message is for the next round, it is compared to the message
-stored in the "next round slot", which again may then be updated
-@end itemize
-
-Finally, when it comes to send the stored message for the current round to
-the neighbors there is a random delay added for each neighbor, to avoid
-traffic spikes and minimize cross-messages.
-
-@cindex HOSTLIST subsystem
-@cindex hostlist subsystem
-@node GNUnet's HOSTLIST subsystem
-@section GNUnet's HOSTLIST subsystem
-
-@c %**end of header
-
-Peers in the GNUnet overlay network need address information so that they
-can connect with other peers. GNUnet uses so called HELLO messages to
-store and exchange peer addresses.
-GNUnet provides several methods for peers to obtain this information:
-
-@itemize @bullet
-@item out-of-band exchange of HELLO messages (manually, using for example
-gnunet-peerinfo)
-@item HELLO messages shipped with GNUnet (automatic with distribution)
-@item UDP neighbor discovery in LAN (IPv4 broadcast, IPv6 multicast)
-@item topology gossiping (learning from other peers we already connected
-to), and
-@item the HOSTLIST daemon covered in this section, which is particularly
-relevant for bootstrapping new peers.
-@end itemize
-
-New peers have no existing connections (and thus cannot learn from gossip
-among peers), may not have other peers in their LAN and might be started
-with an outdated set of HELLO messages from the distribution.
-In this case, getting new peers to connect to the network requires either
-manual effort or the use of a HOSTLIST to obtain HELLOs.
-
-@menu
-* HELLOs::
-* Overview for the HOSTLIST subsystem::
-* Interacting with the HOSTLIST daemon::
-* Hostlist security address validation::
-* The HOSTLIST daemon::
-* The HOSTLIST server::
-* The HOSTLIST client::
-* Usage::
-@end menu
-
-@node HELLOs
-@subsection HELLOs
-
-@c %**end of header
-
-The basic information peers require to connect to other peers are
-contained in so called HELLO messages you can think of as a business card.
-Besides the identity of the peer (based on the cryptographic public key) a
-HELLO message may contain address information that specifies ways to
-contact a peer. By obtaining HELLO messages, a peer can learn how to
-contact other peers.
-
-@node Overview for the HOSTLIST subsystem
-@subsection Overview for the HOSTLIST subsystem
-
-@c %**end of header
-
-The HOSTLIST subsystem provides a way to distribute and obtain contact
-information to connect to other peers using a simple HTTP GET request.
-It's implementation is split in three parts, the main file for the daemon
-itself (@file{gnunet-daemon-hostlist.c}), the HTTP client used to download
-peer information (@file{hostlist-client.c}) and the server component used
-to provide this information to other peers (@file{hostlist-server.c}).
-The server is basically a small HTTP web server (based on GNU
-libmicrohttpd) which provides a list of HELLOs known to the local peer for
-download. The client component is basically a HTTP client
-(based on libcurl) which can download hostlists from one or more websites.
-The hostlist format is a binary blob containing a sequence of HELLO
-messages. Note that any HTTP server can theoretically serve a hostlist,
-the build-in hostlist server makes it simply convenient to offer this
-service.
-
-
-@menu
-* Features::
-* Limitations2::
-@end menu
-
-@node Features
-@subsubsection Features
-
-@c %**end of header
-
-The HOSTLIST daemon can:
-
-@itemize @bullet
-@item provide HELLO messages with validated addresses obtained from
-PEERINFO to download for other peers
-@item download HELLO messages and forward these message to the TRANSPORT
-subsystem for validation
-@item advertises the URL of this peer's hostlist address to other peers
-via gossip
-@item automatically learn about hostlist servers from the gossip of other
-peers
-@end itemize
-
-@node Limitations2
-@subsubsection Limitations2
-
-@c %**end of header
-
-The HOSTLIST daemon does not:
-
-@itemize @bullet
-@item verify the cryptographic information in the HELLO messages
-@item verify the address information in the HELLO messages
-@end itemize
-
-@node Interacting with the HOSTLIST daemon
-@subsection Interacting with the HOSTLIST daemon
-
-@c %**end of header
-
-The HOSTLIST subsystem is currently implemented as a daemon, so there is
-no need for the user to interact with it and therefore there is no
-command line tool and no API to communicate with the daemon. In the
-future, we can envision changing this to allow users to manually trigger
-the download of a hostlist.
-
-Since there is no command line interface to interact with HOSTLIST, the
-only way to interact with the hostlist is to use STATISTICS to obtain or
-modify information about the status of HOSTLIST:
-
-@example
-$ gnunet-statistics -s hostlist
-@end example
-
-@noindent
-In particular, HOSTLIST includes a @strong{persistent} value in statistics
-that specifies when the hostlist server might be queried next. As this
-value is exponentially increasing during runtime, developers may want to
-reset or manually adjust it. Note that HOSTLIST (but not STATISTICS) needs
-to be shutdown if changes to this value are to have any effect on the
-daemon (as HOSTLIST does not monitor STATISTICS for changes to the
-download frequency).
-
-@node Hostlist security address validation
-@subsection Hostlist security address validation
-
-@c %**end of header
-
-Since information obtained from other parties cannot be trusted without
-validation, we have to distinguish between @emph{validated} and
-@emph{not validated} addresses. Before using (and so trusting)
-information from other parties, this information has to be double-checked
-(validated). Address validation is not done by HOSTLIST but by the
-TRANSPORT service.
-
-The HOSTLIST component is functionally located between the PEERINFO and
-the TRANSPORT subsystem. When acting as a server, the daemon obtains valid
-(@emph{validated}) peer information (HELLO messages) from the PEERINFO
-service and provides it to other peers. When acting as a client, it
-contacts the HOSTLIST servers specified in the configuration, downloads
-the (unvalidated) list of HELLO messages and forwards these information
-to the TRANSPORT server to validate the addresses.
-
-@node The HOSTLIST daemon
-@subsection The HOSTLIST daemon
-
-@c %**end of header
-
-The hostlist daemon is the main component of the HOSTLIST subsystem. It is
-started by the ARM service and (if configured) starts the HOSTLIST client
-and server components.
-
-If the daemon provides a hostlist itself it can advertise it's own
-hostlist to other peers. To do so it sends a
-@code{GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT} message to other peers
-when they connect to this peer on the CORE level. This hostlist
-advertisement message contains the URL to access the HOSTLIST HTTP
-server of the sender. The daemon may also subscribe to this type of
-message from CORE service, and then forward these kind of message to the
-HOSTLIST client. The client then uses all available URLs to download peer
-information when necessary.
-
-When starting, the HOSTLIST daemon first connects to the CORE subsystem
-and if hostlist learning is enabled, registers a CORE handler to receive
-this kind of messages. Next it starts (if configured) the client and
-server. It passes pointers to CORE connect and disconnect and receive
-handlers where the client and server store their functions, so the daemon
-can notify them about CORE events.
-
-To clean up on shutdown, the daemon has a cleaning task, shutting down all
-subsystems and disconnecting from CORE.
-
-@node The HOSTLIST server
-@subsection The HOSTLIST server
-
-@c %**end of header
-
-The server provides a way for other peers to obtain HELLOs. Basically it
-is a small web server other peers can connect to and download a list of
-HELLOs using standard HTTP; it may also advertise the URL of the hostlist
-to other peers connecting on CORE level.
-
-
-@menu
-* The HTTP Server::
-* Advertising the URL::
-@end menu
-
-@node The HTTP Server
-@subsubsection The HTTP Server
-
-@c %**end of header
-
-During startup, the server starts a web server listening on the port
-specified with the HTTPPORT value (default 8080). In addition it connects
-to the PEERINFO service to obtain peer information. The HOSTLIST server
-uses the GNUNET_PEERINFO_iterate function to request HELLO information for
-all peers and adds their information to a new hostlist if they are
-suitable (expired addresses and HELLOs without addresses are both not
-suitable) and the maximum size for a hostlist is not exceeded
-(MAX_BYTES_PER_HOSTLISTS = 500000).
-When PEERINFO finishes (with a last NULL callback), the server destroys
-the previous hostlist response available for download on the web server
-and replaces it with the updated hostlist. The hostlist format is
-basically a sequence of HELLO messages (as obtained from PEERINFO) without
-any special tokenization. Since each HELLO message contains a size field,
-the response can easily be split into separate HELLO messages by the
-client.
-
-A HOSTLIST client connecting to the HOSTLIST server will receive the
-hostlist as a HTTP response and the the server will terminate the
-connection with the result code @code{HTTP 200 OK}.
-The connection will be closed immediately if no hostlist is available.
-
-@node Advertising the URL
-@subsubsection Advertising the URL
-
-@c %**end of header
-
-The server also advertises the URL to download the hostlist to other peers
-if hostlist advertisement is enabled.
-When a new peer connects and has hostlist learning enabled, the server
-sends a @code{GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT} message to this
-peer using the CORE service.
-
-@node The HOSTLIST client
-@subsection The HOSTLIST client
-
-@c %**end of header
-
-The client provides the functionality to download the list of HELLOs from
-a set of URLs.
-It performs a standard HTTP request to the URLs configured and learned
-from advertisement messages received from other peers. When a HELLO is
-downloaded, the HOSTLIST client forwards the HELLO to the TRANSPORT
-service for validation.
-
-The client supports two modes of operation:
-
-@itemize @bullet
-@item download of HELLOs (bootstrapping)
-@item learning of URLs
-@end itemize
-
-@menu
-* Bootstrapping::
-* Learning::
-@end menu
-
-@node Bootstrapping
-@subsubsection Bootstrapping
-
-@c %**end of header
-
-For bootstrapping, it schedules a task to download the hostlist from the
-set of known URLs.
-The downloads are only performed if the number of current
-connections is smaller than a minimum number of connections
-(at the moment 4).
-The interval between downloads increases exponentially; however, the
-exponential growth is limited if it becomes longer than an hour.
-At that point, the frequency growth is capped at
-(#number of connections * 1h).
-
-Once the decision has been taken to download HELLOs, the daemon chooses a
-random URL from the list of known URLs. URLs can be configured in the
-configuration or be learned from advertisement messages.
-The client uses a HTTP client library (libcurl) to initiate the download
-using the libcurl multi interface.
-Libcurl passes the data to the callback_download function which
-stores the data in a buffer if space is available and the maximum size for
-a hostlist download is not exceeded (MAX_BYTES_PER_HOSTLISTS = 500000).
-When a full HELLO was downloaded, the HOSTLIST client offers this
-HELLO message to the TRANSPORT service for validation.
-When the download is finished or failed, statistical information about the
-quality of this URL is updated.
-
-@cindex HOSTLIST learning
-@node Learning
-@subsubsection Learning
-
-@c %**end of header
-
-The client also manages hostlist advertisements from other peers. The
-HOSTLIST daemon forwards @code{GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT}
-messages to the client subsystem, which extracts the URL from the message.
-Next, a test of the newly obtained URL is performed by triggering a
-download from the new URL. If the URL works correctly, it is added to the
-list of working URLs.
-
-The size of the list of URLs is restricted, so if an additional server is
-added and the list is full, the URL with the worst quality ranking
-(determined through successful downloads and number of HELLOs e.g.) is
-discarded. During shutdown the list of URLs is saved to a file for
-persistance and loaded on startup. URLs from the configuration file are
-never discarded.
-
-@node Usage
-@subsection Usage
-
-@c %**end of header
-
-To start HOSTLIST by default, it has to be added to the DEFAULTSERVICES
-section for the ARM services. This is done in the default configuration.
-
-For more information on how to configure the HOSTLIST subsystem see the
-installation handbook:@
-Configuring the hostlist to bootstrap@
-Configuring your peer to provide a hostlist
-
-@cindex IDENTITY
-@cindex identity subsystem
-@node GNUnet's IDENTITY subsystem
-@section GNUnet's IDENTITY subsystem
-
-@c %**end of header
-
-Identities of "users" in GNUnet are called egos.
-Egos can be used as pseudonyms ("fake names") or be tied to an
-organization (for example, "GNU") or even the actual identity of a human.
-GNUnet users are expected to have many egos. They might have one tied to
-their real identity, some for organizations they manage, and more for
-different domains where they want to operate under a pseudonym.
-
-The IDENTITY service allows users to manage their egos. The identity
-service manages the private keys egos of the local user; it does not
-manage identities of other users (public keys). Public keys for other
-users need names to become manageable. GNUnet uses the
-@dfn{GNU Name System} (GNS) to give names to other users and manage their
-public keys securely. This chapter is about the IDENTITY service,
-which is about the management of private keys.
-
-On the network, an ego corresponds to an ECDSA key (over Curve25519,
-using RFC 6979, as required by GNS). Thus, users can perform actions
-under a particular ego by using (signing with) a particular private key.
-Other users can then confirm that the action was really performed by that
-ego by checking the signature against the respective public key.
-
-The IDENTITY service allows users to associate a human-readable name with
-each ego. This way, users can use names that will remind them of the
-purpose of a particular ego.
-The IDENTITY service will store the respective private keys and
-allows applications to access key information by name.
-Users can change the name that is locally (!) associated with an ego.
-Egos can also be deleted, which means that the private key will be removed
-and it thus will not be possible to perform actions with that ego in the
-future.
-
-Additionally, the IDENTITY subsystem can associate service functions with
-egos.
-For example, GNS requires the ego that should be used for the shorten
-zone. GNS will ask IDENTITY for an ego for the "gns-short" service.
-The IDENTITY service has a mapping of such service strings to the name of
-the ego that the user wants to use for this service, for example
-"my-short-zone-ego".
-
-Finally, the IDENTITY API provides access to a special ego, the
-anonymous ego. The anonymous ego is special in that its private key is not
-really private, but fixed and known to everyone.
-Thus, anyone can perform actions as anonymous. This can be useful as with
-this trick, code does not have to contain a special case to distinguish
-between anonymous and pseudonymous egos.
-
-@menu
-* libgnunetidentity::
-* The IDENTITY Client-Service Protocol::
-@end menu
-
-@cindex libgnunetidentity
-@node libgnunetidentity
-@subsection libgnunetidentity
-@c %**end of header
-
-
-@menu
-* Connecting to the service::
-* Operations on Egos::
-* The anonymous Ego::
-* Convenience API to lookup a single ego::
-* Associating egos with service functions::
-@end menu
-
-@node Connecting to the service
-@subsubsection Connecting to the service
-
-@c %**end of header
-
-First, typical clients connect to the identity service using
-@code{GNUNET_IDENTITY_connect}. This function takes a callback as a
-parameter.
-If the given callback parameter is non-null, it will be invoked to notify
-the application about the current state of the identities in the system.
-
-@itemize @bullet
-@item First, it will be invoked on all known egos at the time of the
-connection. For each ego, a handle to the ego and the user's name for the
-ego will be passed to the callback. Furthermore, a @code{void **} context
-argument will be provided which gives the client the opportunity to
-associate some state with the ego.
-@item Second, the callback will be invoked with NULL for the ego, the name
-and the context. This signals that the (initial) iteration over all egos
-has completed.
-@item Then, the callback will be invoked whenever something changes about
-an ego.
-If an ego is renamed, the callback is invoked with the ego handle of the
-ego that was renamed, and the new name. If an ego is deleted, the callback
-is invoked with the ego handle and a name of NULL. In the deletion case,
-the application should also release resources stored in the context.
-@item When the application destroys the connection to the identity service
-using @code{GNUNET_IDENTITY_disconnect}, the callback is again invoked
-with the ego and a name of NULL (equivalent to deletion of the egos).
-This should again be used to clean up the per-ego context.
-@end itemize
-
-The ego handle passed to the callback remains valid until the callback is
-invoked with a name of NULL, so it is safe to store a reference to the
-ego's handle.
-
-@node Operations on Egos
-@subsubsection Operations on Egos
-
-@c %**end of header
-
-Given an ego handle, the main operations are to get its associated private
-key using @code{GNUNET_IDENTITY_ego_get_private_key} or its associated
-public key using @code{GNUNET_IDENTITY_ego_get_public_key}.
-
-The other operations on egos are pretty straightforward.
-Using @code{GNUNET_IDENTITY_create}, an application can request the
-creation of an ego by specifying the desired name.
-The operation will fail if that name is
-already in use. Using @code{GNUNET_IDENTITY_rename} the name of an
-existing ego can be changed. Finally, egos can be deleted using
-@code{GNUNET_IDENTITY_delete}. All of these operations will trigger
-updates to the callback given to the @code{GNUNET_IDENTITY_connect}
-function of all applications that are connected with the identity service
-at the time. @code{GNUNET_IDENTITY_cancel} can be used to cancel the
-operations before the respective continuations would be called.
-It is not guaranteed that the operation will not be completed anyway,
-only the continuation will no longer be called.
-
-@node The anonymous Ego
-@subsubsection The anonymous Ego
-
-@c %**end of header
-
-A special way to obtain an ego handle is to call
-@code{GNUNET_IDENTITY_ego_get_anonymous}, which returns an ego for the
-"anonymous" user --- anyone knows and can get the private key for this
-user, so it is suitable for operations that are supposed to be anonymous
-but require signatures (for example, to avoid a special path in the code).
-The anonymous ego is always valid and accessing it does not require a
-connection to the identity service.
-
-@node Convenience API to lookup a single ego
-@subsubsection Convenience API to lookup a single ego
-
-
-As applications commonly simply have to lookup a single ego, there is a
-convenience API to do just that. Use @code{GNUNET_IDENTITY_ego_lookup} to
-lookup a single ego by name. Note that this is the user's name for the
-ego, not the service function. The resulting ego will be returned via a
-callback and will only be valid during that callback. The operation can
-be cancelled via @code{GNUNET_IDENTITY_ego_lookup_cancel}
-(cancellation is only legal before the callback is invoked).
-
-@node Associating egos with service functions
-@subsubsection Associating egos with service functions
-
-
-The @code{GNUNET_IDENTITY_set} function is used to associate a particular
-ego with a service function. The name used by the service and the ego are
-given as arguments.
-Afterwards, the service can use its name to lookup the associated ego
-using @code{GNUNET_IDENTITY_get}.
-
-@node The IDENTITY Client-Service Protocol
-@subsection The IDENTITY Client-Service Protocol
-
-@c %**end of header
-
-A client connecting to the identity service first sends a message with
-type
-@code{GNUNET_MESSAGE_TYPE_IDENTITY_START} to the service. After that, the
-client will receive information about changes to the egos by receiving
-messages of type @code{GNUNET_MESSAGE_TYPE_IDENTITY_UPDATE}.
-Those messages contain the private key of the ego and the user's name of
-the ego (or zero bytes for the name to indicate that the ego was deleted).
-A special bit @code{end_of_list} is used to indicate the end of the
-initial iteration over the identity service's egos.
-
-The client can trigger changes to the egos by sending @code{CREATE},
-@code{RENAME} or @code{DELETE} messages.
-The CREATE message contains the private key and the desired name.@
-The RENAME message contains the old name and the new name.@
-The DELETE message only needs to include the name of the ego to delete.@
-The service responds to each of these messages with a @code{RESULT_CODE}
-message which indicates success or error of the operation, and possibly
-a human-readable error message.
-
-Finally, the client can bind the name of a service function to an ego by
-sending a @code{SET_DEFAULT} message with the name of the service function
-and the private key of the ego.
-Such bindings can then be resolved using a @code{GET_DEFAULT} message,
-which includes the name of the service function. The identity service
-will respond to a GET_DEFAULT request with a SET_DEFAULT message
-containing the respective information, or with a RESULT_CODE to
-indicate an error.
-
-@cindex NAMESTORE
-@cindex namestore subsystem
-@node GNUnet's NAMESTORE Subsystem
-@section GNUnet's NAMESTORE Subsystem
-
-The NAMESTORE subsystem provides persistent storage for local GNS zone
-information. All local GNS zone information are managed by NAMESTORE. It
-provides both the functionality to administer local GNS information (e.g.
-delete and add records) as well as to retrieve GNS information (e.g to
-list name information in a client).
-NAMESTORE does only manage the persistent storage of zone information
-belonging to the user running the service: GNS information from other
-users obtained from the DHT are stored by the NAMECACHE subsystem.
-
-NAMESTORE uses a plugin-based database backend to store GNS information
-with good performance. Here sqlite, MySQL and PostgreSQL are supported
-database backends.
-NAMESTORE clients interact with the IDENTITY subsystem to obtain
-cryptographic information about zones based on egos as described with the
-IDENTITY subsystem, but internally NAMESTORE refers to zones using the
-ECDSA private key.
-In addition, it collaborates with the NAMECACHE subsystem and
-stores zone information when local information are modified in the
-GNS cache to increase look-up performance for local information.
-
-NAMESTORE provides functionality to look-up and store records, to iterate
-over a specific or all zones and to monitor zones for changes. NAMESTORE
-functionality can be accessed using the NAMESTORE api or the NAMESTORE
-command line tool.
-
-@menu
-* libgnunetnamestore::
-@end menu
-
-@cindex libgnunetnamestore
-@node libgnunetnamestore
-@subsection libgnunetnamestore
-
-To interact with NAMESTORE clients first connect to the NAMESTORE service
-using the @code{GNUNET_NAMESTORE_connect} passing a configuration handle.
-As a result they obtain a NAMESTORE handle, they can use for operations,
-or NULL is returned if the connection failed.
-
-To disconnect from NAMESTORE, clients use
-@code{GNUNET_NAMESTORE_disconnect} and specify the handle to disconnect.
-
-NAMESTORE internally uses the ECDSA private key to refer to zones. These
-private keys can be obtained from the IDENTITY subsytem.
-Here @emph{egos} @emph{can be used to refer to zones or the default ego
-assigned to the GNS subsystem can be used to obtained the master zone's
-private key.}
-
-
-@menu
-* Editing Zone Information::
-* Iterating Zone Information::
-* Monitoring Zone Information::
-@end menu
-
-@node Editing Zone Information
-@subsubsection Editing Zone Information
-
-@c %**end of header
-
-NAMESTORE provides functions to lookup records stored under a label in a
-zone and to store records under a label in a zone.
-
-To store (and delete) records, the client uses the
-@code{GNUNET_NAMESTORE_records_store} function and has to provide
-namestore handle to use, the private key of the zone, the label to store
-the records under, the records and number of records plus an callback
-function.
-After the operation is performed NAMESTORE will call the provided
-callback function with the result GNUNET_SYSERR on failure
-(including timeout/queue drop/failure to validate), GNUNET_NO if content
-was already there or not found GNUNET_YES (or other positive value) on
-success plus an additional error message.
-
-Records are deleted by using the store command with 0 records to store.
-It is important to note, that records are not merged when records exist
-with the label.
-So a client has first to retrieve records, merge with existing records
-and then store the result.
-
-To perform a lookup operation, the client uses the
-@code{GNUNET_NAMESTORE_records_store} function. Here he has to pass the
-namestore handle, the private key of the zone and the label. He also has
-to provide a callback function which will be called with the result of
-the lookup operation:
-the zone for the records, the label, and the records including the
-number of records included.
-
-A special operation is used to set the preferred nickname for a zone.
-This nickname is stored with the zone and is automatically merged with
-all labels and records stored in a zone. Here the client uses the
-@code{GNUNET_NAMESTORE_set_nick} function and passes the private key of
-the zone, the nickname as string plus a the callback with the result of
-the operation.
-
-@node Iterating Zone Information
-@subsubsection Iterating Zone Information
-
-@c %**end of header
-
-A client can iterate over all information in a zone or all zones managed
-by NAMESTORE.
-Here a client uses the @code{GNUNET_NAMESTORE_zone_iteration_start}
-function and passes the namestore handle, the zone to iterate over and a
-callback function to call with the result.
-If the client wants to iterate over all the, he passes NULL for the zone.
-A @code{GNUNET_NAMESTORE_ZoneIterator} handle is returned to be used to
-continue iteration.
-
-NAMESTORE calls the callback for every result and expects the client to
-call @code{GNUNET_NAMESTORE_zone_iterator_next} to continue to iterate or
-@code{GNUNET_NAMESTORE_zone_iterator_stop} to interrupt the iteration.
-When NAMESTORE reached the last item it will call the callback with a
-NULL value to indicate.
-
-@node Monitoring Zone Information
-@subsubsection Monitoring Zone Information
-
-@c %**end of header
-
-Clients can also monitor zones to be notified about changes. Here the
-clients uses the @code{GNUNET_NAMESTORE_zone_monitor_start} function and
-passes the private key of the zone and and a callback function to call
-with updates for a zone.
-The client can specify to obtain zone information first by iterating over
-the zone and specify a synchronization callback to be called when the
-client and the namestore are synced.
-
-On an update, NAMESTORE will call the callback with the private key of the
-zone, the label and the records and their number.
-
-To stop monitoring, the client calls
-@code{GNUNET_NAMESTORE_zone_monitor_stop} and passes the handle obtained
-from the function to start the monitoring.
-
-@cindex PEERINFO
-@cindex peerinfo subsystem
-@node GNUnet's PEERINFO subsystem
-@section GNUnet's PEERINFO subsystem
-
-@c %**end of header
-
-The PEERINFO subsystem is used to store verified (validated) information
-about known peers in a persistent way. It obtains these addresses for
-example from TRANSPORT service which is in charge of address validation.
-Validation means that the information in the HELLO message are checked by
-connecting to the addresses and performing a cryptographic handshake to
-authenticate the peer instance stating to be reachable with these
-addresses.
-Peerinfo does not validate the HELLO messages itself but only stores them
-and gives them to interested clients.
-
-As future work, we think about moving from storing just HELLO messages to
-providing a generic persistent per-peer information store.
-More and more subsystems tend to need to store per-peer information in
-persistent way.
-To not duplicate this functionality we plan to provide a PEERSTORE
-service providing this functionality.
-
-@menu
-* Features2::
-* Limitations3::
-* DeveloperPeer Information::
-* Startup::
-* Managing Information::
-* Obtaining Information::
-* The PEERINFO Client-Service Protocol::
-* libgnunetpeerinfo::
-@end menu
-
-@node Features2
-@subsection Features2
-
-@c %**end of header
-
-@itemize @bullet
-@item Persistent storage
-@item Client notification mechanism on update
-@item Periodic clean up for expired information
-@item Differentiation between public and friend-only HELLO
-@end itemize
-
-@node Limitations3
-@subsection Limitations3
-
-
-@itemize @bullet
-@item Does not perform HELLO validation
-@end itemize
-
-@node DeveloperPeer Information
-@subsection DeveloperPeer Information
-
-@c %**end of header
-
-The PEERINFO subsystem stores these information in the form of HELLO messages
-you can think of as business cards. These HELLO messages contain the public key
-of a peer and the addresses a peer can be reached under. The addresses include
-an expiration date describing how long they are valid. This information is
-updated regularly by the TRANSPORT service by revalidating the address. If an
-address is expired and not renewed, it can be removed from the HELLO message.
-
-Some peer do not want to have their HELLO messages distributed to other peers ,
-especially when GNUnet's friend-to-friend modus is enabled. To prevent this
-undesired distribution. PEERINFO distinguishes between @emph{public} and
-@emph{friend-only} HELLO messages. Public HELLO messages can be freely
-distributed to other (possibly unknown) peers (for example using the hostlist,
-gossiping, broadcasting), whereas friend-only HELLO messages may not be
-distributed to other peers. Friend-only HELLO messages have an additional flag
-@code{friend_only} set internally. For public HELLO message this flag is not
-set. PEERINFO does and cannot not check if a client is allowed to obtain a
-specific HELLO type.
-
-The HELLO messages can be managed using the GNUnet HELLO library. Other GNUnet
-systems can obtain these information from PEERINFO and use it for their
-purposes. Clients are for example the HOSTLIST component providing these
-information to other peers in form of a hostlist or the TRANSPORT subsystem
-using these information to maintain connections to other peers.
-
-@node Startup
-@subsection Startup
-
-@c %**end of header
-
-During startup the PEERINFO services loads persistent HELLOs from disk. First
-PEERINFO parses the directory configured in the HOSTS value of the
-@code{PEERINFO} configuration section to store PEERINFO information.@ For all
-files found in this directory valid HELLO messages are extracted. In addition
-it loads HELLO messages shipped with the GNUnet distribution. These HELLOs are
-used to simplify network bootstrapping by providing valid peer information with
-the distribution. The use of these HELLOs can be prevented by setting the
-@code{USE_INCLUDED_HELLOS} in the @code{PEERINFO} configuration section to
-@code{NO}. Files containing invalid information are removed.
-
-@node Managing Information
-@subsection Managing Information
-
-@c %**end of header
-
-The PEERINFO services stores information about known PEERS and a single HELLO
-message for every peer. A peer does not need to have a HELLO if no information
-are available. HELLO information from different sources, for example a HELLO
-obtained from a remote HOSTLIST and a second HELLO stored on disk, are combined
-and merged into one single HELLO message per peer which will be given to
-clients. During this merge process the HELLO is immediately written to disk to
-ensure persistence.
-
-PEERINFO in addition periodically scans the directory where information are
-stored for empty HELLO messages with expired TRANSPORT addresses.@ This
-periodic task scans all files in the directory and recreates the HELLO messages
-it finds. Expired TRANSPORT addresses are removed from the HELLO and if the
-HELLO does not contain any valid addresses, it is discarded and removed from
-disk.
-
-@node Obtaining Information
-@subsection Obtaining Information
-
-@c %**end of header
-
-When a client requests information from PEERINFO, PEERINFO performs a lookup
-for the respective peer or all peers if desired and transmits this information
-to the client. The client can specify if friend-only HELLOs have to be included
-or not and PEERINFO filters the respective HELLO messages before transmitting
-information.
-
-To notify clients about changes to PEERINFO information, PEERINFO maintains a
-list of clients interested in this notifications. Such a notification occurs if
-a HELLO for a peer was updated (due to a merge for example) or a new peer was
-added.
-
-@node The PEERINFO Client-Service Protocol
-@subsection The PEERINFO Client-Service Protocol
-
-@c %**end of header
-
-To connect and disconnect to and from the PEERINFO Service PEERINFO utilizes
-the util client/server infrastructure, so no special messages types are used
-here.
-
-To add information for a peer, the plain HELLO message is transmitted to the
-service without any wrapping. Alle information required are stored within the
-HELLO message. The PEERINFO service provides a message handler accepting and
-processing these HELLO messages.
-
-When obtaining PEERINFO information using the iterate functionality specific
-messages are used. To obtain information for all peers, a @code{struct
-ListAllPeersMessage} with message type
-@code{GNUNET_MESSAGE_TYPE_PEERINFO_GET_ALL} and a flag include_friend_only to
-indicate if friend-only HELLO messages should be included are transmitted. If
-information for a specific peer is required a @code{struct ListAllPeersMessage}
-with @code{GNUNET_MESSAGE_TYPE_PEERINFO_GET} containing the peer identity is
-used.
-
-For both variants the PEERINFO service replies for each HELLO message he wants
-to transmit with a @code{struct ListAllPeersMessage} with type
-@code{GNUNET_MESSAGE_TYPE_PEERINFO_INFO} containing the plain HELLO. The final
-message is @code{struct GNUNET_MessageHeader} with type
-@code{GNUNET_MESSAGE_TYPE_PEERINFO_INFO}. If the client receives this message,
-he can proceed with the next request if any is pending
-
-@node libgnunetpeerinfo
-@subsection libgnunetpeerinfo
-
-@c %**end of header
-
-The PEERINFO API consists mainly of three different functionalities:
-maintaining a connection to the service, adding new information and retrieving
-information form the PEERINFO service.
-
-
-@menu
-* Connecting to the Service::
-* Adding Information::
-* Obtaining Information2::
-@end menu
-
-@node Connecting to the Service
-@subsubsection Connecting to the Service
-
-@c %**end of header
-
-To connect to the PEERINFO service the function @code{GNUNET_PEERINFO_connect}
-is used, taking a configuration handle as an argument, and to disconnect from
-PEERINFO the function @code{GNUNET_PEERINFO_disconnect}, taking the PEERINFO
-handle returned from the connect function has to be called.
-
-@node Adding Information
-@subsubsection Adding Information
-
-@c %**end of header
-
-@code{GNUNET_PEERINFO_add_peer} adds a new peer to the PEERINFO subsystem
-storage. This function takes the PEERINFO handle as an argument, the HELLO
-message to store and a continuation with a closure to be called with the result
-of the operation. The @code{GNUNET_PEERINFO_add_peer} returns a handle to this
-operation allowing to cancel the operation with the respective cancel function
-@code{GNUNET_PEERINFO_add_peer_cancel}. To retrieve information from PEERINFO
-you can iterate over all information stored with PEERINFO or you can tell
-PEERINFO to notify if new peer information are available.
-
-@node Obtaining Information2
-@subsubsection Obtaining Information2
-
-@c %**end of header
-
-To iterate over information in PEERINFO you use @code{GNUNET_PEERINFO_iterate}.
-This function expects the PEERINFO handle, a flag if HELLO messages intended
-for friend only mode should be included, a timeout how long the operation
-should take and a callback with a callback closure to be called for the
-results. If you want to obtain information for a specific peer, you can specify
-the peer identity, if this identity is NULL, information for all peers are
-returned. The function returns a handle to allow to cancel the operation using
-@code{GNUNET_PEERINFO_iterate_cancel}.
-
-To get notified when peer information changes, you can use
-@code{GNUNET_PEERINFO_notify}. This function expects a configuration handle and
-a flag if friend-only HELLO messages should be included. The PEERINFO service
-will notify you about every change and the callback function will be called to
-notify you about changes. The function returns a handle to cancel notifications
-with @code{GNUNET_PEERINFO_notify_cancel}.
-
-
-@node GNUnet's PEERSTORE subsystem
-@section GNUnet's PEERSTORE subsystem
-
-@c %**end of header
-
-GNUnet's PEERSTORE subsystem offers persistent per-peer storage for other
-GNUnet subsystems. GNUnet subsystems can use PEERSTORE to persistently store
-and retrieve arbitrary data. Each data record stored with PEERSTORE contains
-the following fields:
-
-@itemize @bullet
-@item subsystem: Name of the subsystem responsible for the record.
-@item peerid: Identity of the peer this record is related to.
-@item key: a key string identifying the record.
-@item value: binary record value.
-@item expiry: record expiry date.
-@end itemize
-
-@menu
-* Functionality::
-* Architecture::
-* libgnunetpeerstore::
-@end menu
-
-@node Functionality
-@subsection Functionality
-
-@c %**end of header
-
-Subsystems can store any type of value under a (subsystem, peerid, key)
-combination. A "replace" flag set during store operations forces the PEERSTORE
-to replace any old values stored under the same (subsystem, peerid, key)
-combination with the new value. Additionally, an expiry date is set after which
-the record is *possibly* deleted by PEERSTORE.
-
-Subsystems can iterate over all values stored under any of the following
-combination of fields:
-
-@itemize @bullet
-@item (subsystem)
-@item (subsystem, peerid)
-@item (subsystem, key)
-@item (subsystem, peerid, key)
-@end itemize
-
-Subsystems can also request to be notified about any new values stored under a
-(subsystem, peerid, key) combination by sending a "watch" request to
-PEERSTORE.
-
-@node Architecture
-@subsection Architecture
-
-@c %**end of header
-
-PEERSTORE implements the following components:
-
-@itemize @bullet
-@item PEERSTORE service: Handles store, iterate and watch operations.
-@item PEERSTORE API: API to be used by other subsystems to communicate and
-issue commands to the PEERSTORE service.
-@item PEERSTORE plugins: Handles the persistent storage. At the moment, only an
-"sqlite" plugin is implemented.
-@end itemize
-
-@node libgnunetpeerstore
-@subsection libgnunetpeerstore
-
-@c %**end of header
-
-libgnunetpeerstore is the library containing the PEERSTORE API. Subsystems
-wishing to communicate with the PEERSTORE service use this API to open a
-connection to PEERSTORE. This is done by calling
-@code{GNUNET_PEERSTORE_connect} which returns a handle to the newly created
-connection. This handle has to be used with any further calls to the API.
-
-To store a new record, the function @code{GNUNET_PEERSTORE_store} is to be used
-which requires the record fields and a continuation function that will be
-called by the API after the STORE request is sent to the PEERSTORE service.
-Note that calling the continuation function does not mean that the record is
-successfully stored, only that the STORE request has been successfully sent to
-the PEERSTORE service. @code{GNUNET_PEERSTORE_store_cancel} can be called to
-cancel the STORE request only before the continuation function has been called.
-
-To iterate over stored records, the function @code{GNUNET_PEERSTORE_iterate} is
-to be used. @emph{peerid} and @emph{key} can be set to NULL. An iterator
-callback function will be called with each matching record found and a NULL
-record at the end to signal the end of result set.
-@code{GNUNET_PEERSTORE_iterate_cancel} can be used to cancel the ITERATE
-request before the iterator callback is called with a NULL record.
-
-To be notified with new values stored under a (subsystem, peerid, key)
-combination, the function @code{GNUNET_PEERSTORE_watch} is to be used. This
-will register the watcher with the PEERSTORE service, any new records matching
-the given combination will trigger the callback function passed to
-@code{GNUNET_PEERSTORE_watch}. This continues until
-@code{GNUNET_PEERSTORE_watch_cancel} is called or the connection to the service
-is destroyed.
-
-After the connection is no longer needed, the function
-@code{GNUNET_PEERSTORE_disconnect} can be called to disconnect from the
-PEERSTORE service. Any pending ITERATE or WATCH requests will be destroyed. If
-the @code{sync_first} flag is set to @code{GNUNET_YES}, the API will delay the
-disconnection until all pending STORE requests are sent to the PEERSTORE
-service, otherwise, the pending STORE requests will be destroyed as well.
-
-@node GNUnet's SET Subsystem
-@section GNUnet's SET Subsystem
-
-@c %**end of header
-
-The SET service implements efficient set operations between two peers over a
-mesh tunnel. Currently, set union and set intersection are the only supported
-operations. Elements of a set consist of an @emph{element type} and arbitrary
-binary @emph{data}. The size of an element's data is limited to around 62
-KB.
-
-@menu
-* Local Sets::
-* Set Modifications::
-* Set Operations::
-* Result Elements::
-* libgnunetset::
-* The SET Client-Service Protocol::
-* The SET Intersection Peer-to-Peer Protocol::
-* The SET Union Peer-to-Peer Protocol::
-@end menu
-
-@node Local Sets
-@subsection Local Sets
-
-@c %**end of header
-
-Sets created by a local client can be modified and reused for multiple
-operations. As each set operation requires potentially expensive special
-auxilliary data to be computed for each element of a set, a set can only
-participate in one type of set operation (i.e. union or intersection). The type
-of a set is determined upon its creation. If a the elements of a set are needed
-for an operation of a different type, all of the set's element must be copied
-to a new set of appropriate type.
-
-@node Set Modifications
-@subsection Set Modifications
-
-@c %**end of header
-
-Even when set operations are active, one can add to and remove elements from a
-set. However, these changes will only be visible to operations that have been
-created after the changes have taken place. That is, every set operation only
-sees a snapshot of the set from the time the operation was started. This
-mechanism is @emph{not} implemented by copying the whole set, but by attaching
-@emph{generation information} to each element and operation.
-
-@node Set Operations
-@subsection Set Operations
-
-@c %**end of header
-
-Set operations can be started in two ways: Either by accepting an operation
-request from a remote peer, or by requesting a set operation from a remote
-peer. Set operations are uniquely identified by the involved @emph{peers}, an
-@emph{application id} and the @emph{operation type}.
-
-The client is notified of incoming set operations by @emph{set listeners}. A
-set listener listens for incoming operations of a specific operation type and
-application id. Once notified of an incoming set request, the client can
-accept the set request (providing a local set for the operation) or reject
-it.
-
-@node Result Elements
-@subsection Result Elements
-
-@c %**end of header
-
-The SET service has three @emph{result modes} that determine how an operation's
-result set is delivered to the client:
-
-@itemize @bullet
-@item @strong{Full Result Set.} All elements of set resulting from the set
-operation are returned to the client.
-@item @strong{Added Elements.} Only elements that result from the operation and
-are not already in the local peer's set are returned. Note that for some
-operations (like set intersection) this result mode will never return any
-elements. This can be useful if only the remove peer is actually interested in
-the result of the set operation.
-@item @strong{Removed Elements.} Only elements that are in the local peer's
-initial set but not in the operation's result set are returned. Note that for
-some operations (like set union) this result mode will never return any
-elements. This can be useful if only the remove peer is actually interested in
-the result of the set operation.
-@end itemize
-
-@node libgnunetset
-@subsection libgnunetset
-
-@c %**end of header
-
-@menu
-* Sets::
-* Listeners::
-* Operations::
-* Supplying a Set::
-* The Result Callback::
-@end menu
-
-@node Sets
-@subsubsection Sets
-
-@c %**end of header
-
-New sets are created with @code{GNUNET_SET_create}. Both the local peer's
-configuration (as each set has its own client connection) and the operation
-type must be specified. The set exists until either the client calls
-@code{GNUNET_SET_destroy} or the client's connection to the service is
-disrupted. In the latter case, the client is notified by the return value of
-functions dealing with sets. This return value must always be checked.
-
-Elements are added and removed with @code{GNUNET_SET_add_element} and
-@code{GNUNET_SET_remove_element}.
-
-@node Listeners
-@subsubsection Listeners
-
-@c %**end of header
-
-Listeners are created with @code{GNUNET_SET_listen}. Each time time a remote
-peer suggests a set operation with an application id and operation type
-matching a listener, the listener's callack is invoked. The client then must
-synchronously call either @code{GNUNET_SET_accept} or @code{GNUNET_SET_reject}.
-Note that the operation will not be started until the client calls
-@code{GNUNET_SET_commit} (see Section "Supplying a Set").
-
-@node Operations
-@subsubsection Operations
-
-@c %**end of header
-
-Operations to be initiated by the local peer are created with
-@code{GNUNET_SET_prepare}. Note that the operation will not be started until
-the client calls @code{GNUNET_SET_commit} (see Section "Supplying a
-Set").
-
-@node Supplying a Set
-@subsubsection Supplying a Set
-
-@c %**end of header
-
-To create symmetry between the two ways of starting a set operation (accepting
-and nitiating it), the operation handles returned by @code{GNUNET_SET_accept}
-and @code{GNUNET_SET_prepare} do not yet have a set to operate on, thus they
-can not do any work yet.
-
-The client must call @code{GNUNET_SET_commit} to specify a set to use for an
-operation. @code{GNUNET_SET_commit} may only be called once per set
-operation.
-
-@node The Result Callback
-@subsubsection The Result Callback
-
-@c %**end of header
-
-Clients must specify both a result mode and a result callback with
-@code{GNUNET_SET_accept} and @code{GNUNET_SET_prepare}. The result callback
-with a status indicating either that an element was received, or the operation
-failed or succeeded. The interpretation of the received element depends on the
-result mode. The callback needs to know which result mode it is used in, as the
-arguments do not indicate if an element is part of the full result set, or if
-it is in the difference between the original set and the final set.
-
-@node The SET Client-Service Protocol
-@subsection The SET Client-Service Protocol
-
-@c %**end of header
-
-@menu
-* Creating Sets::
-* Listeners2::
-* Initiating Operations::
-* Modifying Sets::
-* Results and Operation Status::
-* Iterating Sets::
-@end menu
-
-@node Creating Sets
-@subsubsection Creating Sets
-
-@c %**end of header
-
-For each set of a client, there exists a client connection to the service. Sets
-are created by sending the @code{GNUNET_SERVICE_SET_CREATE} message over a new
-client connection. Multiple operations for one set are multiplexed over one
-client connection, using a request id supplied by the client.
-
-@node Listeners2
-@subsubsection Listeners2
-
-@c %**end of header
-
-Each listener also requires a seperate client connection. By sending the
-@code{GNUNET_SERVICE_SET_LISTEN} message, the client notifies the service of
-the application id and operation type it is interested in. A client rejects an
-incoming request by sending @code{GNUNET_SERVICE_SET_REJECT} on the listener's
-client connection. In contrast, when accepting an incoming request, a a
-@code{GNUNET_SERVICE_SET_ACCEPT} message must be sent over the@ set that is
-supplied for the set operation.
-
-@node Initiating Operations
-@subsubsection Initiating Operations
-
-@c %**end of header
-
-Operations with remote peers are initiated by sending a
-@code{GNUNET_SERVICE_SET_EVALUATE} message to the service. The@ client
-connection that this message is sent by determines the set to use.
-
-@node Modifying Sets
-@subsubsection Modifying Sets
-
-@c %**end of header
-
-Sets are modified with the @code{GNUNET_SERVICE_SET_ADD} and
-@code{GNUNET_SERVICE_SET_REMOVE} messages.
-
-
-@c %@menu
-@c %* Results and Operation Status::
-@c %* Iterating Sets::
-@c %@end menu
-
-@node Results and Operation Status
-@subsubsection Results and Operation Status
-@c %**end of header
-
-The service notifies the client of result elements and success/failure of a set
-operation with the @code{GNUNET_SERVICE_SET_RESULT} message.
-
-@node Iterating Sets
-@subsubsection Iterating Sets
-
-@c %**end of header
-
-All elements of a set can be requested by sending
-@code{GNUNET_SERVICE_SET_ITER_REQUEST}. The server responds with
-@code{GNUNET_SERVICE_SET_ITER_ELEMENT} and eventually terminates the iteration
-with @code{GNUNET_SERVICE_SET_ITER_DONE}. After each received element, the
-client@ must send @code{GNUNET_SERVICE_SET_ITER_ACK}. Note that only one set
-iteration may be active for a set at any given time.
-
-@node The SET Intersection Peer-to-Peer Protocol
-@subsection The SET Intersection Peer-to-Peer Protocol
-
-@c %**end of header
-
-The intersection protocol operates over CADET and starts with a
-GNUNET_MESSAGE_TYPE_SET_P2P_OPERATION_REQUEST being sent by the peer initiating
-the operation to the peer listening for inbound requests. It includes the
-number of elements of the initiating peer, which is used to decide which side
-will send a Bloom filter first.
-
-The listening peer checks if the operation type and application identifier are
-acceptable for its current state. If not, it responds with a
-GNUNET_MESSAGE_TYPE_SET_RESULT and a status of GNUNET_SET_STATUS_FAILURE (and
-terminates the CADET channel).
-
-If the application accepts the request, the listener sends back a@
-GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_ELEMENT_INFO if it has more elements
-in the set than the client. Otherwise, it immediately starts with the Bloom
-filter exchange. If the initiator receives a
-GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_ELEMENT_INFO response, it beings the
-Bloom filter exchange, unless the set size is indicated to be zero, in which
-case the intersection is considered finished after just the initial
-handshake.
-
-
-@menu
-* The Bloom filter exchange::
-* Salt::
-@end menu
-
-@node The Bloom filter exchange
-@subsubsection The Bloom filter exchange
-
-@c %**end of header
-
-In this phase, each peer transmits a Bloom filter over the remaining keys of
-the local set to the other peer using a
-GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_BF message. This message additionally
-includes the number of elements left in the sender's set, as well as the XOR
-over all of the keys in that set.
-
-The number of bits 'k' set per element in the Bloom filter is calculated based
-on the relative size of the two sets. Furthermore, the size of the Bloom filter
-is calculated based on 'k' and the number of elements in the set to maximize
-the amount of data filtered per byte transmitted on the wire (while avoiding an
-excessively high number of iterations).
-
-The receiver of the message removes all elements from its local set that do not
-pass the Bloom filter test. It then checks if the set size of the sender and
-the XOR over the keys match what is left of his own set. If they do, he sends
-a@ GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_DONE back to indicate that the
-latest set is the final result. Otherwise, the receiver starts another Bloom
-fitler exchange, except this time as the sender.
-
-@node Salt
-@subsubsection Salt
-
-@c %**end of header
-
-Bloomfilter operations are probablistic: With some non-zero probability the
-test may incorrectly say an element is in the set, even though it is not.
-
-To mitigate this problem, the intersection protocol iterates exchanging Bloom
-filters using a different random 32-bit salt in each iteration (the salt is
-also included in the message). With different salts, set operations may fail
-for different elements. Merging the results from the executions, the
-probability of failure drops to zero.
-
-The iterations terminate once both peers have established that they have sets
-of the same size, and where the XOR over all keys computes the same 512-bit
-value (leaving a failure probability of 2-511).
-
-@node The SET Union Peer-to-Peer Protocol
-@subsection The SET Union Peer-to-Peer Protocol
-
-@c %**end of header
-
-The SET union protocol is based on Eppstein's efficient set reconciliation
-without prior context. You should read this paper first if you want to
-understand the protocol.
-
-The union protocol operates over CADET and starts with a
-GNUNET_MESSAGE_TYPE_SET_P2P_OPERATION_REQUEST being sent by the peer initiating
-the operation to the peer listening for inbound requests. It includes the
-number of elements of the initiating peer, which is currently not used.
-
-The listening peer checks if the operation type and application identifier are
-acceptable for its current state. If not, it responds with a
-GNUNET_MESSAGE_TYPE_SET_RESULT and a status of GNUNET_SET_STATUS_FAILURE (and
-terminates the CADET channel).
-
-If the application accepts the request, it sends back a strata estimator using
-a message of type GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SE. The initiator evaluates
-the strata estimator and initiates the exchange of invertible Bloom filters,
-sending a GNUNET_MESSAGE_TYPE_SET_UNION_P2P_IBF.
-
-During the IBF exchange, if the receiver cannot invert the Bloom filter or
-detects a cycle, it sends a larger IBF in response (up to a defined maximum
-limit; if that limit is reached, the operation fails). Elements decoded while
-processing the IBF are transmitted to the other peer using
-GNUNET_MESSAGE_TYPE_SET_P2P_ELEMENTS, or requested from the other peer using
-GNUNET_MESSAGE_TYPE_SET_P2P_ELEMENT_REQUESTS messages, depending on the sign
-observed during decoding of the IBF. Peers respond to a
-GNUNET_MESSAGE_TYPE_SET_P2P_ELEMENT_REQUESTS message with the respective
-element in a GNUNET_MESSAGE_TYPE_SET_P2P_ELEMENTS message. If the IBF fully
-decodes, the peer responds with a GNUNET_MESSAGE_TYPE_SET_UNION_P2P_DONE
-message instead of another GNUNET_MESSAGE_TYPE_SET_UNION_P2P_IBF.
-
-All Bloom filter operations use a salt to mingle keys before hasing them into
-buckets, such that future iterations have a fresh chance of succeeding if they
-failed due to collisions before.
-
-@node GNUnet's STATISTICS subsystem
-@section GNUnet's STATISTICS subsystem
-
-@c %**end of header
-
-In GNUnet, the STATISTICS subsystem offers a central place for all subsystems
-to publish unsigned 64-bit integer run-time statistics. Keeping this
-information centrally means that there is a unified way for the user to obtain
-data on all subsystems, and individual subsystems do not have to always include
-a custom data export method for performance metrics and other statistics. For
-example, the TRANSPORT system uses STATISTICS to update information about the
-number of directly connected peers and the bandwidth that has been consumed by
-the various plugins. This information is valuable for diagnosing connectivity
-and performance issues.
-
-Following the GNUnet service architecture, the STATISTICS subsystem is divided
-into an API which is exposed through the header
-@strong{gnunet_statistics_service.h} and the STATISTICS service
-@strong{gnunet-service-statistics}. The @strong{gnunet-statistics} command-line
-tool can be used to obtain (and change) information about the values stored by
-the STATISTICS service. The STATISTICS service does not communicate with other
-peers.
-
-Data is stored in the STATISTICS service in the form of tuples
-@strong{(subsystem, name, value, persistence)}. The subsystem determines to
-which other GNUnet's subsystem the data belongs. name is the name through which
-value is associated. It uniquely identifies the record from among other records
-belonging to the same subsystem. In some parts of the code, the pair
-@strong{(subsystem, name)} is called a @strong{statistic} as it identifies the
-values stored in the STATISTCS service.The persistence flag determines if the
-record has to be preserved across service restarts. A record is said to be
-persistent if this flag is set for it; if not, the record is treated as a
-non-persistent record and it is lost after service restart. Persistent records
-are written to and read from the file @strong{statistics.data} before shutdown
-and upon startup. The file is located in the HOME directory of the peer.
-
-An anomaly of the STATISTICS service is that it does not terminate immediately
-upon receiving a shutdown signal if it has any clients connected to it. It
-waits for all the clients that are not monitors to close their connections
-before terminating itself. This is to prevent the loss of data during peer
-shutdown --- delaying the STATISTICS service shutdown helps other services to
-store important data to STATISTICS during shutdown.
-
-@menu
-* libgnunetstatistics::
-* The STATISTICS Client-Service Protocol::
-@end menu
-
-@node libgnunetstatistics
-@subsection libgnunetstatistics
-
-@c %**end of header
-
-@strong{libgnunetstatistics} is the library containing the API for the
-STATISTICS subsystem. Any process requiring to use STATISTICS should use this
-API by to open a connection to the STATISTICS service. This is done by calling
-the function @code{GNUNET_STATISTICS_create()}. This function takes the
-subsystem's name which is trying to use STATISTICS and a configuration. All
-values written to STATISTICS with this connection will be placed in the section
-corresponding to the given subsystem's name. The connection to STATISTICS can
-be destroyed with the function GNUNET_STATISTICS_destroy(). This function
-allows for the connection to be destroyed immediately or upon transferring all
-pending write requests to the service.
-
-Note: STATISTICS subsystem can be disabled by setting @code{DISABLE = YES}
-under the @code{[STATISTICS]} section in the configuration. With such a
-configuration all calls to @code{GNUNET_STATISTICS_create()} return @code{NULL}
-as the STATISTICS subsystem is unavailable and no other functions from the API
-can be used.
-
-
-@menu
-* Statistics retrieval::
-* Setting statistics and updating them::
-* Watches::
-@end menu
-
-@node Statistics retrieval
-@subsubsection Statistics retrieval
-
-@c %**end of header
-
-Once a connection to the statistics service is obtained, information about any
-other system which uses statistics can be retrieved with the function
-GNUNET_STATISTICS_get(). This function takes the connection handle, the name of
-the subsystem whose information we are interested in (a @code{NULL} value will
-retrieve information of all available subsystems using STATISTICS), the name of
-the statistic we are interested in (a @code{NULL} value will retrieve all
-available statistics), a continuation callback which is called when all of
-requested information is retrieved, an iterator callback which is called for
-each parameter in the retrieved information and a closure for the
-aforementioned callbacks. The library then invokes the iterator callback for
-each value matching the request.
-
-Call to @code{GNUNET_STATISTICS_get()} is asynchronous and can be canceled with
-the function @code{GNUNET_STATISTICS_get_cancel()}. This is helpful when
-retrieving statistics takes too long and especially when we want to shutdown
-and cleanup everything.
-
-@node Setting statistics and updating them
-@subsubsection Setting statistics and updating them
-
-@c %**end of header
-
-So far we have seen how to retrieve statistics, here we will learn how we can
-set statistics and update them so that other subsystems can retrieve them.
-
-A new statistic can be set using the function @code{GNUNET_STATISTICS_set()}.
-This function takes the name of the statistic and its value and a flag to make
-the statistic persistent. The value of the statistic should be of the type
-@code{uint64_t}. The function does not take the name of the subsystem; it is
-determined from the previous @code{GNUNET_STATISTICS_create()} invocation. If
-the given statistic is already present, its value is overwritten.
-
-An existing statistics can be updated, i.e its value can be increased or
-decreased by an amount with the function @code{GNUNET_STATISTICS_update()}. The
-parameters to this function are similar to @code{GNUNET_STATISTICS_set()},
-except that it takes the amount to be changed as a type @code{int64_t} instead
-of the value.
-
-The library will combine multiple set or update operations into one message if
-the client performs requests at a rate that is faster than the available IPC
-with the STATISTICS service. Thus, the client does not have to worry about
-sending requests too quickly.
-
-@node Watches
-@subsubsection Watches
-
-@c %**end of header
-
-As interesting feature of STATISTICS lies in serving notifications whenever a
-statistic of our interest is modified. This is achieved by registering a watch
-through the function @code{GNUNET_STATISTICS_watch()}. The parameters of this
-function are similar to those of @code{GNUNET_STATISTICS_get()}. Changes to the
-respective statistic's value will then cause the given iterator callback to be
-called. Note: A watch can only be registered for a specific statistic. Hence
-the subsystem name and the parameter name cannot be @code{NULL} in a call to
-@code{GNUNET_STATISTICS_watch()}.
-
-A registered watch will keep notifying any value changes until
-@code{GNUNET_STATISTICS_watch_cancel()} is called with the same parameters that
-are used for registering the watch.
-
-@node The STATISTICS Client-Service Protocol
-@subsection The STATISTICS Client-Service Protocol
-@c %**end of header
-
-
-@menu
-* Statistics retrieval2::
-* Setting and updating statistics::
-* Watching for updates::
-@end menu
-
-@node Statistics retrieval2
-@subsubsection Statistics retrieval2
-
-@c %**end of header
-
-To retrieve statistics, the client transmits a message of type
-@code{GNUNET_MESSAGE_TYPE_STATISTICS_GET} containing the given subsystem name
-and statistic parameter to the STATISTICS service. The service responds with a
-message of type @code{GNUNET_MESSAGE_TYPE_STATISTICS_VALUE} for each of the
-statistics parameters that match the client request for the client. The end of
-information retrieved is signaled by the service by sending a message of type
-@code{GNUNET_MESSAGE_TYPE_STATISTICS_END}.
-
-@node Setting and updating statistics
-@subsubsection Setting and updating statistics
-
-@c %**end of header
-
-The subsystem name, parameter name, its value and the persistence flag are
-communicated to the service through the message
-@code{GNUNET_MESSAGE_TYPE_STATISTICS_SET}.
-
-When the service receives a message of type
-@code{GNUNET_MESSAGE_TYPE_STATISTICS_SET}, it retrieves the subsystem name and
-checks for a statistic parameter with matching the name given in the message.
-If a statistic parameter is found, the value is overwritten by the new value
-from the message; if not found then a new statistic parameter is created with
-the given name and value.
-
-In addition to just setting an absolute value, it is possible to perform a
-relative update by sending a message of type
-@code{GNUNET_MESSAGE_TYPE_STATISTICS_SET} with an update flag
-(@code{GNUNET_STATISTICS_SETFLAG_RELATIVE}) signifying that the value in the
-message should be treated as an update value.
-
-@node Watching for updates
-@subsubsection Watching for updates
-
-@c %**end of header
-
-The function registers the watch at the service by sending a message of type
-@code{GNUNET_MESSAGE_TYPE_STATISTICS_WATCH}. The service then sends
-notifications through messages of type
-@code{GNUNET_MESSAGE_TYPE_STATISTICS_WATCH_VALUE} whenever the statistic
-parameter's value is changed.
-
-@node GNUnet's Distributed Hash Table (DHT)
-@section GNUnet's Distributed Hash Table (DHT)
-
-@c %**end of header
-
-GNUnet includes a generic distributed hash table that can be used by developers
-building P2P applications in the framework. This section documents high-level
-features and how developers are expected to use the DHT. We have a research
-paper detailing how the DHT works. Also, Nate's thesis includes a detailed
-description and performance analysis (in chapter 6).
-
-Key features of GNUnet's DHT include:
-
-@itemize @bullet
-@item stores key-value pairs with values up to (approximately) 63k in size
-@item works with many underlay network topologies (small-world, random graph),
-underlay does not need to be a full mesh / clique
-@item support for extended queries (more than just a simple 'key'), filtering
-duplicate replies within the network (bloomfilter) and content validation (for
-details, please read the subsection on the block library)
-@item can (optionally) return paths taken by the PUT and GET operations to the
-application
-@item provides content replication to handle churn
-@end itemize
-
-GNUnet's DHT is randomized and unreliable. Unreliable means that there is no
-strict guarantee that a value stored in the DHT is always found --- values are
-only found with high probability. While this is somewhat true in all P2P DHTs,
-GNUnet developers should be particularly wary of this fact (this will help you
-write secure, fault-tolerant code). Thus, when writing any application using
-the DHT, you should always consider the possibility that a value stored in the
-DHT by you or some other peer might simply not be returned, or returned with a
-significant delay. Your application logic must be written to tolerate this
-(naturally, some loss of performance or quality of service is expected in this
-case).
-
-@menu
-* Block library and plugins::
-* libgnunetdht::
-* The DHT Client-Service Protocol::
-* The DHT Peer-to-Peer Protocol::
-@end menu
-
-@node Block library and plugins
-@subsection Block library and plugins
-
-@c %**end of header
-
-@menu
-* What is a Block?::
-* The API of libgnunetblock::
-* Queries::
-* Sample Code::
-* Conclusion2::
-@end menu
-
-@node What is a Block?
-@subsubsection What is a Block?
-
-@c %**end of header
-
-Blocks are small (< 63k) pieces of data stored under a key (struct
-GNUNET_HashCode). Blocks have a type (enum GNUNET_BlockType) which defines
-their data format. Blocks are used in GNUnet as units of static data exchanged
-between peers and stored (or cached) locally. Uses of blocks include
-file-sharing (the files are broken up into blocks), the VPN (DNS information is
-stored in blocks) and the DHT (all information in the DHT and meta-information
-for the maintenance of the DHT are both stored using blocks). The block
-subsystem provides a few common functions that must be available for any type
-of block.
-
-@node The API of libgnunetblock
-@subsubsection The API of libgnunetblock
-
-@c %**end of header
-
-The block library requires for each (family of) block type(s) a block plugin
-(implementing gnunet_block_plugin.h) that provides basic functions that are
-needed by the DHT (and possibly other subsystems) to manage the block. These
-block plugins are typically implemented within their respective subsystems.@
-The main block library is then used to locate, load and query the appropriate
-block plugin. Which plugin is appropriate is determined by the block type
-(which is just a 32-bit integer). Block plugins contain code that specifies
-which block types are supported by a given plugin. The block library loads all
-block plugins that are installed at the local peer and forwards the application
-request to the respective plugin.
-
-The central functions of the block APIs (plugin and main library) are to allow
-the mapping of blocks to their respective key (if possible) and the ability to
-check that a block is well-formed and matches a given request (again, if
-possible). This way, GNUnet can avoid storing invalid blocks, storing blocks
-under the wrong key and forwarding blocks in response to a query that they do
-not answer.
-
-One key function of block plugins is that it allows GNUnet to detect duplicate
-replies (via the Bloom filter). All plugins MUST support detecting duplicate
-replies (by adding the current response to the Bloom filter and rejecting it if
-it is encountered again). If a plugin fails to do this, responses may loop in
-the network.
-
-@node Queries
-@subsubsection Queries
-@c %**end of header
-
-The query format for any block in GNUnet consists of four main components.
-First, the type of the desired block must be specified. Second, the query must
-contain a hash code. The hash code is used for lookups in hash tables and
-databases and must not be unique for the block (however, if possible a unique
-hash should be used as this would be best for performance). Third, an optional
-Bloom filter can be specified to exclude known results; replies that hash to
-the bits set in the Bloom filter are considered invalid. False-positives can be
-eliminated by sending the same query again with a different Bloom filter
-mutator value, which parameterizes the hash function that is used. Finally, an
-optional application-specific "eXtended query" (xquery) can be specified to
-further constrain the results. It is entirely up to the type-specific plugin to
-determine whether or not a given block matches a query (type, hash, Bloom
-filter, and xquery). Naturally, not all xquery's are valid and some types of
-blocks may not support Bloom filters either, so the plugin also needs to check
-if the query is valid in the first place.
-
-Depending on the results from the plugin, the DHT will then discard the
-(invalid) query, forward the query, discard the (invalid) reply, cache the
-(valid) reply, and/or forward the (valid and non-duplicate) reply.
-
-@node Sample Code
-@subsubsection Sample Code
-
-@c %**end of header
-
-The source code in @strong{plugin_block_test.c} is a good starting point for
-new block plugins --- it does the minimal work by implementing a plugin that
-performs no validation at all. The respective @strong{Makefile.am} shows how to
-build and install a block plugin.
-
-@node Conclusion2
-@subsubsection Conclusion2
-
-@c %**end of header
-
-In conclusion, GNUnet subsystems that want to use the DHT need to define a
-block format and write a plugin to match queries and replies. For testing, the
-"GNUNET_BLOCK_TYPE_TEST" block type can be used; it accepts any query as valid
-and any reply as matching any query. This type is also used for the DHT command
-line tools. However, it should NOT be used for normal applications due to the
-lack of error checking that results from this primitive implementation.
-
-@node libgnunetdht
-@subsection libgnunetdht
-
-@c %**end of header
-
-The DHT API itself is pretty simple and offers the usual GET and PUT functions
-that work as expected. The specified block type refers to the block library
-which allows the DHT to run application-specific logic for data stored in the
-network.
-
-
-@menu
-* GET::
-* PUT::
-* MONITOR::
-* DHT Routing Options::
-@end menu
-
-@node GET
-@subsubsection GET
-
-@c %**end of header
-
-When using GET, the main consideration for developers (other than the block
-library) should be that after issuing a GET, the DHT will continuously cause
-(small amounts of) network traffic until the operation is explicitly canceled.
-So GET does not simply send out a single network request once; instead, the
-DHT will continue to search for data. This is needed to achieve good success
-rates and also handles the case where the respective PUT operation happens
-after the GET operation was started. Developers should not cancel an existing
-GET operation and then explicitly re-start it to trigger a new round of
-network requests; this is simply inefficient, especially as the internal
-automated version can be more efficient, for example by filtering results in
-the network that have already been returned.
-
-If an application that performs a GET request has a set of replies that it
-already knows and would like to filter, it can call@
-@code{GNUNET_DHT_get_filter_known_results} with an array of hashes over the
-respective blocks to tell the DHT that these results are not desired (any
-more). This way, the DHT will filter the respective blocks using the block
-library in the network, which may result in a significant reduction in
-bandwidth consumption.
-
-@node PUT
-@subsubsection PUT
-
-@c %**end of header
-
-In contrast to GET operations, developers @strong{must} manually re-run PUT
-operations periodically (if they intend the content to continue to be
-available). Content stored in the DHT expires or might be lost due to churn.
-Furthermore, GNUnet's DHT typically requires multiple rounds of PUT operations
-before a key-value pair is consistently available to all peers (the DHT
-randomizes paths and thus storage locations, and only after multiple rounds of
-PUTs there will be a sufficient number of replicas in large DHTs). An explicit
-PUT operation using the DHT API will only cause network traffic once, so in
-order to ensure basic availability and resistance to churn (and adversaries),
-PUTs must be repeated. While the exact frequency depends on the application, a
-rule of thumb is that there should be at least a dozen PUT operations within
-the content lifetime. Content in the DHT typically expires after one day, so
-DHT PUT operations should be repeated at least every 1-2 hours.
-
-@node MONITOR
-@subsubsection MONITOR
-
-@c %**end of header
-
-The DHT API also allows applications to monitor messages crossing the local
-DHT service. The types of messages used by the DHT are GET, PUT and RESULT
-messages. Using the monitoring API, applications can choose to monitor these
-requests, possibly limiting themselves to requests for a particular block
-type.
-
-The monitoring API is not only usefu only for diagnostics, it can also be used
-to trigger application operations based on PUT operations. For example, an
-application may use PUTs to distribute work requests to other peers. The
-workers would then monitor for PUTs that give them work, instead of looking
-for work using GET operations. This can be beneficial, especially if the
-workers have no good way to guess the keys under which work would be stored.
-Naturally, additional protocols might be needed to ensure that the desired
-number of workers will process the distributed workload.
-
-@node DHT Routing Options
-@subsubsection DHT Routing Options
-
-@c %**end of header
-
-There are two important options for GET and PUT requests:
-
-@table @asis
-@item GNUNET_DHT_RO_DEMULITPLEX_EVERYWHERE This option means that all peers
-should process the request, even if their peer ID is not closest to the key.
-For a PUT request, this means that all peers that a request traverses may make
-a copy of the data. Similarly for a GET request, all peers will check their
-local database for a result. Setting this option can thus significantly improve
-caching and reduce bandwidth consumption --- at the expense of a larger DHT
-database. If in doubt, we recommend that this option should be used.
-@item GNUNET_DHT_RO_RECORD_ROUTE This option instructs the DHT to record the path
-that a GET or a PUT request is taking through the overlay network. The
-resulting paths are then returned to the application with the respective
-result. This allows the receiver of a result to construct a path to the
-originator of the data, which might then be used for routing. Naturally,
-setting this option requires additional bandwidth and disk space, so
-applications should only set this if the paths are needed by the application
-logic.
-@item GNUNET_DHT_RO_FIND_PEER This option is an internal option used by
-the DHT's peer discovery mechanism and should not be used by applications.
-@item GNUNET_DHT_RO_BART This option is currently not implemented. It may in
-the future offer performance improvements for clique topologies.
-@end table
-
-@node The DHT Client-Service Protocol
-@subsection The DHT Client-Service Protocol
-
-@c %**end of header
-
-@menu
-* PUTting data into the DHT::
-* GETting data from the DHT::
-* Monitoring the DHT::
-@end menu
-
-@node PUTting data into the DHT
-@subsubsection PUTting data into the DHT
-
-@c %**end of header
-
-To store (PUT) data into the DHT, the client sends a@ @code{struct
-GNUNET_DHT_ClientPutMessage} to the service. This message specifies the block
-type, routing options, the desired replication level, the expiration time, key,
-value and a 64-bit unique ID for the operation. The service responds with a@
-@code{struct GNUNET_DHT_ClientPutConfirmationMessage} with the same 64-bit
-unique ID. Note that the service sends the confirmation as soon as it has
-locally processed the PUT request. The PUT may still be propagating through the
-network at this time.
-
-In the future, we may want to change this to provide (limited) feedback to the
-client, for example if we detect that the PUT operation had no effect because
-the same key-value pair was already stored in the DHT. However, changing this
-would also require additional state and messages in the P2P
-interaction.
-
-@node GETting data from the DHT
-@subsubsection GETting data from the DHT
-
-@c %**end of header
-
-To retrieve (GET) data from the DHT, the client sends a@ @code{struct
-GNUNET_DHT_ClientGetMessage} to the service. The message specifies routing
-options, a replication level (for replicating the GET, not the content), the
-desired block type, the key, the (optional) extended query and unique 64-bit
-request ID.
-
-Additionally, the client may send any number of@ @code{struct
-GNUNET_DHT_ClientGetResultSeenMessage}s to notify the service about results
-that the client is already aware of. These messages consist of the key, the
-unique 64-bit ID of the request, and an arbitrary number of hash codes over the
-blocks that the client is already aware of. As messages are restricted to 64k,
-a client that already knows more than about a thousand blocks may need to send
-several of these messages. Naturally, the client should transmit these messages
-as quickly as possible after the original GET request such that the DHT can
-filter those results in the network early on. Naturally, as these messages are
-send after the original request, it is conceivalbe that the DHT service may
-return blocks that match those already known to the client anyway.
-
-In response to a GET request, the service will send @code{struct
-GNUNET_DHT_ClientResultMessage}s to the client. These messages contain the
-block type, expiration, key, unique ID of the request and of course the value
-(a block). Depending on the options set for the respective operations, the
-replies may also contain the path the GET and/or the PUT took through the
-network.
-
-A client can stop receiving replies either by disconnecting or by sending a
-@code{struct GNUNET_DHT_ClientGetStopMessage} which must contain the key and
-the 64-bit unique ID of the original request. Using an explicit "stop" message
-is more common as this allows a client to run many concurrent GET operations
-over the same connection with the DHT service --- and to stop them
-individually.
-
-@node Monitoring the DHT
-@subsubsection Monitoring the DHT
-
-@c %**end of header
-
-To begin monitoring, the client sends a @code{struct
-GNUNET_DHT_MonitorStartStop} message to the DHT service. In this message, flags
-can be set to enable (or disable) monitoring of GET, PUT and RESULT messages
-that pass through a peer. The message can also restrict monitoring to a
-particular block type or a particular key. Once monitoring is enabled, the DHT
-service will notify the client about any matching event using @code{struct
-GNUNET_DHT_MonitorGetMessage}s for GET events, @code{struct
-GNUNET_DHT_MonitorPutMessage} for PUT events and@ @code{struct
-GNUNET_DHT_MonitorGetRespMessage} for RESULTs. Each of these messages contains
-all of the information about the event.
-
-@node The DHT Peer-to-Peer Protocol
-@subsection The DHT Peer-to-Peer Protocol
-@c %**end of header
-
-
-@menu
-* Routing GETs or PUTs::
-* PUTting data into the DHT2::
-* GETting data from the DHT2::
-@end menu
-
-@node Routing GETs or PUTs
-@subsubsection Routing GETs or PUTs
-
-@c %**end of header
-
-When routing GETs or PUTs, the DHT service selects a suitable subset of
-neighbours for forwarding. The exact number of neighbours can be zero or more
-and depends on the hop counter of the query (initially zero) in relation to the
-(log of) the network size estimate, the desired replication level and the
-peer's connectivity. Depending on the hop counter and our network size
-estimate, the selection of the peers maybe randomized or by proximity to the
-key. Furthermore, requests include a set of peers that a request has already
-traversed; those peers are also excluded from the selection.
-
-@node PUTting data into the DHT2
-@subsubsection PUTting data into the DHT2
-
-@c %**end of header
-
-To PUT data into the DHT, the service sends a @code{struct PeerPutMessage} of
-type @code{GNUNET_MESSAGE_TYPE_DHT_P2P_PUT} to the respective neighbour. In
-addition to the usual information about the content (type, routing options,
-desired replication level for the content, expiration time, key and value), the
-message contains a fixed-size Bloom filter with information about which peers
-(may) have already seen this request. This Bloom filter is used to ensure that
-DHT messages never loop back to a peer that has already processed the request.
-Additionally, the message includes the current hop counter and, depending on
-the routing options, the message may include the full path that the message has
-taken so far. The Bloom filter should already contain the identity of the
-previous hop; however, the path should not include the identity of the previous
-hop and the receiver should append the identity of the sender to the path, not
-its own identity (this is done to reduce bandwidth).
-
-@node GETting data from the DHT2
-@subsubsection GETting data from the DHT2
-
-@c %**end of header
-
-A peer can search the DHT by sending @code{struct PeerGetMessage}s of type
-@code{GNUNET_MESSAGE_TYPE_DHT_P2P_GET} to other peers. In addition to the usual
-information about the request (type, routing options, desired replication level
-for the request, the key and the extended query), a GET request also again
-contains a hop counter, a Bloom filter over the peers that have processed the
-request already and depending on the routing options the full path traversed by
-the GET. Finally, a GET request includes a variable-size second Bloom filter
-and a so-called Bloom filter mutator value which together indicate which
-replies the sender has already seen. During the lookup, each block that matches
-they block type, key and extended query is additionally subjected to a test
-against this Bloom filter. The block plugin is expected to take the hash of the
-block and combine it with the mutator value and check if the result is not yet
-in the Bloom filter. The originator of the query will from time to time modify
-the mutator to (eventually) allow false-positives filtered by the Bloom filter
-to be returned.
-
-Peers that receive a GET request perform a local lookup (depending on their
-proximity to the key and the query options) and forward the request to other
-peers. They then remember the request (including the Bloom filter for blocking
-duplicate results) and when they obtain a matching, non-filtered response a
-@code{struct PeerResultMessage} of type@
-@code{GNUNET_MESSAGE_TYPE_DHT_P2P_RESULT} is forwarded to the previous hop.
-Whenver a result is forwarded, the block plugin is used to update the Bloom
-filter accordingly, to ensure that the same result is never forwarded more than
-once. The DHT service may also cache forwarded results locally if the
-"CACHE_RESULTS" option is set to "YES" in the configuration.
-
-@node The GNU Name System (GNS)
-@section The GNU Name System (GNS)
-
-@c %**end of header
-
-The GNU Name System (GNS) is a decentralized database that enables users to
-securely resolve names to values. Names can be used to identify other users
-(for example, in social networking), or network services (for example, VPN
-services running at a peer in GNUnet, or purely IP-based services on the
-Internet). Users interact with GNS by typing in a hostname that ends in ".gnu"
-or ".zkey".
-
-Videos giving an overview of most of the GNS and the motivations behind it is
-available here and here. The remainder of this chapter targets developers that
-are familiar with high level concepts of GNS as presented in these talks.
-
-GNS-aware applications should use the GNS resolver to obtain the respective
-records that are stored under that name in GNS. Each record consists of a type,
-value, expiration time and flags.
-
-The type specifies the format of the value. Types below 65536 correspond to DNS
-record types, larger values are used for GNS-specific records. Applications can
-define new GNS record types by reserving a number and implementing a plugin
-(which mostly needs to convert the binary value representation to a
-human-readable text format and vice-versa). The expiration time specifies how
-long the record is to be valid. The GNS API ensures that applications are only
-given non-expired values. The flags are typically irrelevant for applications,
-as GNS uses them internally to control visibility and validity of records.
-
-Records are stored along with a signature. The signature is generated using the
-private key of the authoritative zone. This allows any GNS resolver to verify
-the correctness of a name-value mapping.
-
-Internally, GNS uses the NAMECACHE to cache information obtained from other
-users, the NAMESTORE to store information specific to the local users, and the
-DHT to exchange data between users. A plugin API is used to enable applications
-to define new GNS record types.
-
-@menu
-* libgnunetgns::
-* libgnunetgnsrecord::
-* GNS plugins::
-* The GNS Client-Service Protocol::
-* Hijacking the DNS-Traffic using gnunet-service-dns::
-* Serving DNS lookups via GNS on W32::
-@end menu
-
-@node libgnunetgns
-@subsection libgnunetgns
-
-@c %**end of header
-
-The GNS API itself is extremely simple. Clients first connec to the GNS service
-using @code{GNUNET_GNS_connect}. They can then perform lookups using
-@code{GNUNET_GNS_lookup} or cancel pending lookups using
-@code{GNUNET_GNS_lookup_cancel}. Once finished, clients disconnect using
-@code{GNUNET_GNS_disconnect}.
-
-
-@menu
-* Looking up records::
-* Accessing the records::
-* Creating records::
-* Future work::
-@end menu
-
-@node Looking up records
-@subsubsection Looking up records
-
-@c %**end of header
-
-@code{GNUNET_GNS_lookup} takes a number of arguments:
-
-@table @asis
-@item handle This is simply the GNS connection handle from
-@code{GNUNET_GNS_connect}.
-@item name The client needs to specify the name to
-be resolved. This can be any valid DNS or GNS hostname.
-@item zone The client
-needs to specify the public key of the GNS zone against which the resolution
-should be done (the ".gnu" zone). Note that a key must be provided, even if the
-name ends in ".zkey". This should typically be the public key of the
-master-zone of the user.
-@item type This is the desired GNS or DNS record type
-to look for. While all records for the given name will be returned, this can be
-important if the client wants to resolve record types that themselves delegate
-resolution, such as CNAME, PKEY or GNS2DNS. Resolving a record of any of these
-types will only work if the respective record type is specified in the request,
-as the GNS resolver will otherwise follow the delegation and return the records
-from the respective destination, instead of the delegating record.
-@item only_cached This argument should typically be set to @code{GNUNET_NO}. Setting
-it to @code{GNUNET_YES} disables resolution via the overlay network.
-@item shorten_zone_key If GNS encounters new names during resolution, their
-respective zones can automatically be learned and added to the "shorten zone".
-If this is desired, clients must pass the private key of the shorten zone. If
-NULL is passed, shortening is disabled.
-@item proc This argument identifies
-the function to call with the result. It is given proc_cls, the number of
-records found (possilby zero) and the array of the records as arguments. proc
-will only be called once. After proc,> has been called, the lookup must no
-longer be cancelled.
-@item proc_cls The closure for proc.
-@end table
-
-@node Accessing the records
-@subsubsection Accessing the records
-
-@c %**end of header
-
-The @code{libgnunetgnsrecord} library provides an API to manipulate the GNS
-record array that is given to proc. In particular, it offers functions such as
-converting record values to human-readable strings (and back). However, most
-@code{libgnunetgnsrecord} functions are not interesting to GNS client
-applications.
-
-For DNS records, the @code{libgnunetdnsparser} library provides functions for
-parsing (and serializing) common types of DNS records.
-
-@node Creating records
-@subsubsection Creating records
-
-@c %**end of header
-
-Creating GNS records is typically done by building the respective record
-information (possibly with the help of @code{libgnunetgnsrecord} and
-@code{libgnunetdnsparser}) and then using the @code{libgnunetnamestore} to
-publish the information. The GNS API is not involved in this
-operation.
-
-@node Future work
-@subsubsection Future work
-
-@c %**end of header
-
-In the future, we want to expand @code{libgnunetgns} to allow applications to
-observe shortening operations performed during GNS resolution, for example so
-that users can receive visual feedback when this happens.
-
-@node libgnunetgnsrecord
-@subsection libgnunetgnsrecord
-
-@c %**end of header
-
-The @code{libgnunetgnsrecord} library is used to manipulate GNS records (in
-plaintext or in their encrypted format). Applications mostly interact with
-@code{libgnunetgnsrecord} by using the functions to convert GNS record values
-to strings or vice-versa, or to lookup a GNS record type number by name (or
-vice-versa). The library also provides various other functions that are mostly
-used internally within GNS, such as converting keys to names, checking for
-expiration, encrypting GNS records to GNS blocks, verifying GNS block
-signatures and decrypting GNS records from GNS blocks.
-
-We will now discuss the four commonly used functions of the API.@
-@code{libgnunetgnsrecord} does not perform these operations itself, but instead
-uses plugins to perform the operation. GNUnet includes plugins to support
-common DNS record types as well as standard GNS record types.
-
-
-@menu
-* Value handling::
-* Type handling::
-@end menu
-
-@node Value handling
-@subsubsection Value handling
-
-@c %**end of header
-
-@code{GNUNET_GNSRECORD_value_to_string} can be used to convert the (binary)
-representation of a GNS record value to a human readable, 0-terminated UTF-8
-string. NULL is returned if the specified record type is not supported by any
-available plugin.
-
-@code{GNUNET_GNSRECORD_string_to_value} can be used to try to convert a human
-readable string to the respective (binary) representation of a GNS record
-value.
-
-@node Type handling
-@subsubsection Type handling
-
-@c %**end of header
-
-@code{GNUNET_GNSRECORD_typename_to_number} can be used to obtain the numeric
-value associated with a given typename. For example, given the typename "A"
-(for DNS A reocrds), the function will return the number 1. A list of common
-DNS record types is
-@uref{http://en.wikipedia.org/wiki/List_of_DNS_record_types, here. Note that
-not all DNS record types are supported by GNUnet GNSRECORD plugins at this
-time.}
-
-@code{GNUNET_GNSRECORD_number_to_typename} can be used to obtain the typename
-associated with a given numeric value. For example, given the type number 1,
-the function will return the typename "A".
-
-@node GNS plugins
-@subsection GNS plugins
-
-@c %**end of header
-
-Adding a new GNS record type typically involves writing (or extending) a
-GNSRECORD plugin. The plugin needs to implement the
-@code{gnunet_gnsrecord_plugin.h} API which provides basic functions that are
-needed by GNSRECORD to convert typenames and values of the respective record
-type to strings (and back). These gnsrecord plugins are typically implemented
-within their respective subsystems. Examples for such plugins can be found in
-the GNSRECORD, GNS and CONVERSATION subsystems.
-
-The @code{libgnunetgnsrecord} library is then used to locate, load and query
-the appropriate gnsrecord plugin. Which plugin is appropriate is determined by
-the record type (which is just a 32-bit integer). The @code{libgnunetgnsrecord}
-library loads all block plugins that are installed at the local peer and
-forwards the application request to the plugins. If the record type is not
-supported by the plugin, it should simply return an error code.
-
-The central functions of the block APIs (plugin and main library) are the same
-four functions for converting between values and strings, and typenames and
-numbers documented in the previous subsection.
-
-@node The GNS Client-Service Protocol
-@subsection The GNS Client-Service Protocol
-
-@c %**end of header
-
-The GNS client-service protocol consists of two simple messages, the
-@code{LOOKUP} message and the @code{LOOKUP_RESULT}. Each @code{LOOKUP} message
-contains a unique 32-bit identifier, which will be included in the
-corresponding response. Thus, clients can send many lookup requests in parallel
-and receive responses out-of-order. A @code{LOOKUP} request also includes the
-public key of the GNS zone, the desired record type and fields specifying
-whether shortening is enabled or networking is disabled. Finally, the
-@code{LOOKUP} message includes the name to be resolved.
-
-The response includes the number of records and the records themselves in the
-format created by @code{GNUNET_GNSRECORD_records_serialize}. They can thus be
-deserialized using @code{GNUNET_GNSRECORD_records_deserialize}.
-
-@node Hijacking the DNS-Traffic using gnunet-service-dns
-@subsection Hijacking the DNS-Traffic using gnunet-service-dns
-
-@c %**end of header
-
-This section documents how the gnunet-service-dns (and the gnunet-helper-dns)
-intercepts DNS queries from the local system.@ This is merely one method for
-how we can obtain GNS queries. It is also possible to change @code{resolv.conf}
-to point to a machine running @code{gnunet-dns2gns} or to modify libc's name
-system switch (NSS) configuration to include a GNS resolution plugin. The
-method described in this chaper is more of a last-ditch catch-all approach.
-
-@code{gnunet-service-dns} enables intercepting DNS traffic using policy based
-routing. We MARK every outgoing DNS-packet if it was not sent by our
-application. Using a second routing table in the Linux kernel these marked
-packets are then routed through our virtual network interface and can thus be
-captured unchanged.
-
-Our application then reads the query and decides how to handle it: A query to
-an address ending in ".gnu" or ".zkey" is hijacked by @code{gnunet-service-gns}
-and resolved internally using GNS. In the future, a reverse query for an
-address of the configured virtual network could be answered with records kept
-about previous forward queries. Queries that are not hijacked by some
-application using the DNS service will be sent to the original recipient. The
-answer to the query will always be sent back through the virtual interface with
-the original nameserver as source address.
-
-
-@menu
-* Network Setup Details::
-@end menu
-
-@node Network Setup Details
-@subsubsection Network Setup Details
-
-@c %**end of header
-
-The DNS interceptor adds the following rules to the Linux kernel:
-@example
-iptables -t mangle -I OUTPUT 1 -p udp --sport $LOCALPORT --dport 53 -j
-ACCEPT iptables -t mangle -I OUTPUT 2 -p udp --dport 53 -j MARK --set-mark 3 ip
-rule add fwmark 3 table2 ip route add default via $VIRTUALDNS table2
-@end example
-
-Line 1 makes sure that all packets coming from a port our application opened
-beforehand (@code{$LOCALPORT}) will be routed normally. Line 2 marks every
-other packet to a DNS-Server with mark 3 (chosen arbitrarily). The third line
-adds a routing policy based on this mark 3 via the routing table.
-
-@node Serving DNS lookups via GNS on W32
-@subsection Serving DNS lookups via GNS on W32
-
-@c %**end of header
-
-This section documents how the libw32nsp (and gnunet-gns-helper-service-w32) do
-DNS resolutions of DNS queries on the local system. This only applies to GNUnet
-running on W32.
-
-W32 has a concept of "Namespaces" and "Namespace providers". These are used to
-present various name systems to applications in a generic way. Namespaces
-include DNS, mDNS, NLA and others. For each namespace any number of providers
-could be registered, and they are queried in an order of priority (which is
-adjustable).
-
-Applications can resolve names by using WSALookupService*() family of
-functions.
-
-However, these are WSA-only facilities. Common BSD socket functions for
-namespace resolutions are gethostbyname and getaddrinfo (among others). These
-functions are implemented internally (by default - by mswsock, which also
-implements the default DNS provider) as wrappers around WSALookupService*()
-functions (see "Sample Code for a Service Provider" on MSDN).
-
-On W32 GNUnet builds a libw32nsp - a namespace provider, which can then be
-installed into the system by using w32nsp-install (and uninstalled by
-w32nsp-uninstall), as described in "Installation Handbook".
-
-libw32nsp is very simple and has almost no dependencies. As a response to
-NSPLookupServiceBegin(), it only checks that the provider GUID passed to it by
-the caller matches GNUnet DNS Provider GUID, checks that name being resolved
-ends in ".gnu" or ".zkey", then connects to gnunet-gns-helper-service-w32 at
-127.0.0.1:5353 (hardcoded) and sends the name resolution request there,
-returning the connected socket to the caller.
-
-When the caller invokes NSPLookupServiceNext(), libw32nsp reads a completely
-formed reply from that socket, unmarshalls it, then gives it back to the
-caller.
-
-At the moment gnunet-gns-helper-service-w32 is implemented to ever give only
-one reply, and subsequent calls to NSPLookupServiceNext() will fail with
-WSA_NODATA (first call to NSPLookupServiceNext() might also fail if GNS failed
-to find the name, or there was an error connecting to it).
-
-gnunet-gns-helper-service-w32 does most of the processing:
-
-@itemize @bullet
-@item Maintains a connection to GNS.
-@item Reads GNS config and loads appropriate keys.
-@item Checks service GUID and decides on the type of record to look up,
-refusing to make a lookup outright when unsupported service GUID is passed.
-@item Launches the lookup
-@end itemize
-
-When lookup result arrives, gnunet-gns-helper-service-w32 forms a complete
-reply (including filling a WSAQUERYSETW structure and, possibly, a binary blob
-with a hostent structure for gethostbyname() client), marshalls it, and sends
-it back to libw32nsp. If no records were found, it sends an empty header.
-
-This works for most normal applications that use gethostbyname() or
-getaddrinfo() to resolve names, but fails to do anything with applications that
-use alternative means of resolving names (such as sending queries to a DNS
-server directly by themselves). This includes some of well known utilities,
-like "ping" and "nslookup".
-
-@node The GNS Namecache
-@section The GNS Namecache
-
-@c %**end of header
-
-The NAMECACHE subsystem is responsible for caching (encrypted) resolution
-results of the GNU Name System (GNS). GNS makes zone information available to
-other users via the DHT. However, as accessing the DHT for every lookup is
-expensive (and as the DHT's local cache is lost whenever the peer is
-restarted), GNS uses the NAMECACHE as a more persistent cache for DHT lookups.
-Thus, instead of always looking up every name in the DHT, GNS first checks if
-the result is already available locally in the NAMECACHE. Only if there is no
-result in the NAMECACHE, GNS queries the DHT. The NAMECACHE stores data in the
-same (encrypted) format as the DHT. It thus makes no sense to iterate over all
-items in the NAMECACHE --- the NAMECACHE does not have a way to provide the
-keys required to decrypt the entries.
-
-Blocks in the NAMECACHE share the same expiration mechanism as blocks in the
-DHT --- the block expires wheneever any of the records in the (encrypted) block
-expires. The expiration time of the block is the only information stored in
-plaintext. The NAMECACHE service internally performs all of the required work
-to expire blocks, clients do not have to worry about this. Also, given that
-NAMECACHE stores only GNS blocks that local users requested, there is no
-configuration option to limit the size of the NAMECACHE. It is assumed to be
-always small enough (a few MB) to fit on the drive.
-
-The NAMECACHE supports the use of different database backends via a plugin API.
-
-@menu
-* libgnunetnamecache::
-* The NAMECACHE Client-Service Protocol::
-* The NAMECACHE Plugin API::
-@end menu
-
-@node libgnunetnamecache
-@subsection libgnunetnamecache
-
-@c %**end of header
-
-The NAMECACHE API consists of five simple functions. First, there is
-@code{GNUNET_NAMECACHE_connect} to connect to the NAMECACHE service. This
-returns the handle required for all other operations on the NAMECACHE. Using
-@code{GNUNET_NAMECACHE_block_cache} clients can insert a block into the cache.
-@code{GNUNET_NAMECACHE_lookup_block} can be used to lookup blocks that were
-stored in the NAMECACHE. Both operations can be cancelled using
-@code{GNUNET_NAMECACHE_cancel}. Note that cancelling a
-@code{GNUNET_NAMECACHE_block_cache} operation can result in the block being
-stored in the NAMECACHE --- or not. Cancellation primarily ensures that the
-continuation function with the result of the operation will no longer be
-invoked. Finally, @code{GNUNET_NAMECACHE_disconnect} closes the connection to
-the NAMECACHE.
-
-The maximum size of a block that can be stored in the NAMECACHE is
-@code{GNUNET_NAMECACHE_MAX_VALUE_SIZE}, which is defined to be 63 kB.
-
-@node The NAMECACHE Client-Service Protocol
-@subsection The NAMECACHE Client-Service Protocol
-
-@c %**end of header
-
-All messages in the NAMECACHE IPC protocol start with the @code{struct
-GNUNET_NAMECACHE_Header} which adds a request ID (32-bit integer) to the
-standard message header. The request ID is used to match requests with the
-respective responses from the NAMECACHE, as they are allowed to happen
-out-of-order.
-
-
-@menu
-* Lookup::
-* Store::
-@end menu
-
-@node Lookup
-@subsubsection Lookup
-
-@c %**end of header
-
-The @code{struct LookupBlockMessage} is used to lookup a block stored in the
-cache. It contains the query hash. The NAMECACHE always responds with a
-@code{struct LookupBlockResponseMessage}. If the NAMECACHE has no response, it
-sets the expiration time in the response to zero. Otherwise, the response is
-expected to contain the expiration time, the ECDSA signature, the derived key
-and the (variable-size) encrypted data of the block.
-
-@node Store
-@subsubsection Store
-
-@c %**end of header
-
-The @code{struct BlockCacheMessage} is used to cache a block in the NAMECACHE.
-It has the same structure as the @code{struct LookupBlockResponseMessage}. The
-service responds with a @code{struct BlockCacheResponseMessage} which contains
-the result of the operation (success or failure). In the future, we might want
-to make it possible to provide an error message as well.
-
-@node The NAMECACHE Plugin API
-@subsection The NAMECACHE Plugin API
-@c %**end of header
-
-The NAMECACHE plugin API consists of two functions, @code{cache_block} to store
-a block in the database, and @code{lookup_block} to lookup a block in the
-database.
-
-
-@menu
-* Lookup2::
-* Store2::
-@end menu
-
-@node Lookup2
-@subsubsection Lookup2
-
-@c %**end of header
-
-The @code{lookup_block} function is expected to return at most one block to the
-iterator, and return @code{GNUNET_NO} if there were no non-expired results. If
-there are multiple non-expired results in the cache, the lookup is supposed to
-return the result with the largest expiration time.
-
-@node Store2
-@subsubsection Store2
-
-@c %**end of header
-
-The @code{cache_block} function is expected to try to store the block in the
-database, and return @code{GNUNET_SYSERR} if this was not possible for any
-reason. Furthermore, @code{cache_block} is expected to implicitly perform cache
-maintenance and purge blocks from the cache that have expired. Note that
-@code{cache_block} might encounter the case where the database already has
-another block stored under the same key. In this case, the plugin must ensure
-that the block with the larger expiration time is preserved. Obviously, this
-can done either by simply adding new blocks and selecting for the most recent
-expiration time during lookup, or by checking which block is more recent during
-the store operation.
-
-@node The REVOCATION Subsystem
-@section The REVOCATION Subsystem
-@c %**end of header
-
-The REVOCATION subsystem is responsible for key revocation of Egos. If a user
-learns that his private key has been compromised or has lost it, he can use the
-REVOCATION system to inform all of the other users that this private key is no
-longer valid. The subsystem thus includes ways to query for the validity of
-keys and to propagate revocation messages.
-
-@menu
-* Dissemination::
-* Revocation Message Design Requirements::
-* libgnunetrevocation::
-* The REVOCATION Client-Service Protocol::
-* The REVOCATION Peer-to-Peer Protocol::
-@end menu
-
-@node Dissemination
-@subsection Dissemination
-
-@c %**end of header
-
-When a revocation is performed, the revocation is first of all disseminated by
-flooding the overlay network. The goal is to reach every peer, so that when a
-peer needs to check if a key has been revoked, this will be purely a local
-operation where the peer looks at his local revocation list. Flooding the
-network is also the most robust form of key revocation --- an adversary would
-have to control a separator of the overlay graph to restrict the propagation of
-the revocation message. Flooding is also very easy to implement --- peers that
-receive a revocation message for a key that they have never seen before simply
-pass the message to all of their neighbours.
-
-Flooding can only distribute the revocation message to peers that are online.
-In order to notify peers that join the network later, the revocation service
-performs efficient set reconciliation over the sets of known revocation
-messages whenever two peers (that both support REVOCATION dissemination)
-connect. The SET service is used to perform this operation
-efficiently.
-
-@node Revocation Message Design Requirements
-@subsection Revocation Message Design Requirements
-
-@c %**end of header
-
-However, flooding is also quite costly, creating O(|E|) messages on a network
-with |E| edges. Thus, revocation messages are required to contain a
-proof-of-work, the result of an expensive computation (which, however, is cheap
-to verify). Only peers that have expended the CPU time necessary to provide
-this proof will be able to flood the network with the revocation message. This
-ensures that an attacker cannot simply flood the network with millions of
-revocation messages. The proof-of-work required by GNUnet is set to take days
-on a typical PC to compute; if the ability to quickly revoke a key is needed,
-users have the option to pre-compute revocation messages to store off-line and
-use instantly after their key has expired.
-
-Revocation messages must also be signed by the private key that is being
-revoked. Thus, they can only be created while the private key is in the
-possession of the respective user. This is another reason to create a
-revocation message ahead of time and store it in a secure location.
-
-@node libgnunetrevocation
-@subsection libgnunetrevocation
-
-@c %**end of header
-
-The REVOCATION API consists of two parts, to query and to issue
-revocations.
-
-
-@menu
-* Querying for revoked keys::
-* Preparing revocations::
-* Issuing revocations::
-@end menu
-
-@node Querying for revoked keys
-@subsubsection Querying for revoked keys
-
-@c %**end of header
-
-@code{GNUNET_REVOCATION_query} is used to check if a given ECDSA public key has
-been revoked. The given callback will be invoked with the result of the check.
-The query can be cancelled using @code{GNUNET_REVOCATION_query_cancel} on the
-return value.
-
-@node Preparing revocations
-@subsubsection Preparing revocations
-
-@c %**end of header
-
-It is often desirable to create a revocation record ahead-of-time and store it
-in an off-line location to be used later in an emergency. This is particularly
-true for GNUnet revocations, where performing the revocation operation itself
-is computationally expensive and thus is likely to take some time. Thus, if
-users want the ability to perform revocations quickly in an emergency, they
-must pre-compute the revocation message. The revocation API enables this with
-two functions that are used to compute the revocation message, but not trigger
-the actual revocation operation.
-
-@code{GNUNET_REVOCATION_check_pow} should be used to calculate the
-proof-of-work required in the revocation message. This function takes the
-public key, the required number of bits for the proof of work (which in GNUnet
-is a network-wide constant) and finally a proof-of-work number as arguments.
-The function then checks if the given proof-of-work number is a valid proof of
-work for the given public key. Clients preparing a revocation are expected to
-call this function repeatedly (typically with a monotonically increasing
-sequence of numbers of the proof-of-work number) until a given number satisfies
-the check. That number should then be saved for later use in the revocation
-operation.
-
-@code{GNUNET_REVOCATION_sign_revocation} is used to generate the signature that
-is required in a revocation message. It takes the private key that (possibly in
-the future) is to be revoked and returns the signature. The signature can again
-be saved to disk for later use, which will then allow performing a revocation
-even without access to the private key.
-
-@node Issuing revocations
-@subsubsection Issuing revocations
-
-
-Given a ECDSA public key, the signature from @code{GNUNET_REVOCATION_sign} and
-the proof-of-work, @code{GNUNET_REVOCATION_revoke} can be used to perform the
-actual revocation. The given callback is called upon completion of the
-operation. @code{GNUNET_REVOCATION_revoke_cancel} can be used to stop the
-library from calling the continuation; however, in that case it is undefined
-whether or not the revocation operation will be executed.
-
-@node The REVOCATION Client-Service Protocol
-@subsection The REVOCATION Client-Service Protocol
-
-
-The REVOCATION protocol consists of four simple messages.
-
-A @code{QueryMessage} containing a public ECDSA key is used to check if a
-particular key has been revoked. The service responds with a
-@code{QueryResponseMessage} which simply contains a bit that says if the given
-public key is still valid, or if it has been revoked.
-
-The second possible interaction is for a client to revoke a key by passing a
-@code{RevokeMessage} to the service. The @code{RevokeMessage} contains the
-ECDSA public key to be revoked, a signature by the corresponding private key
-and the proof-of-work, The service responds with a
-@code{RevocationResponseMessage} which can be used to indicate that the
-@code{RevokeMessage} was invalid (i.e. proof of work incorrect), or otherwise
-indicates that the revocation has been processed successfully.
-
-@node The REVOCATION Peer-to-Peer Protocol
-@subsection The REVOCATION Peer-to-Peer Protocol
-
-@c %**end of header
-
-Revocation uses two disjoint ways to spread revocation information among peers.
-First of all, P2P gossip exchanged via CORE-level neighbours is used to quickly
-spread revocations to all connected peers. Second, whenever two peers (that
-both support revocations) connect, the SET service is used to compute the union
-of the respective revocation sets.
-
-In both cases, the exchanged messages are @code{RevokeMessage}s which contain
-the public key that is being revoked, a matching ECDSA signature, and a
-proof-of-work. Whenever a peer learns about a new revocation this way, it first
-validates the signature and the proof-of-work, then stores it to disk
-(typically to a file $GNUNET_DATA_HOME/revocation.dat) and finally spreads the
-information to all directly connected neighbours.
-
-For computing the union using the SET service, the peer with the smaller hashed
-peer identity will connect (as a "client" in the two-party set protocol) to the
-other peer after one second (to reduce traffic spikes on connect) and initiate
-the computation of the set union. All revocation services use a common hash to
-identify the SET operation over revocation sets.
-
-The current implementation accepts revocation set union operations from all
-peers at any time; however, well-behaved peers should only initiate this
-operation once after establishing a connection to a peer with a larger hashed
-peer identity.
-
-@node GNUnet's File-sharing (FS) Subsystem
-@section GNUnet's File-sharing (FS) Subsystem
-
-@c %**end of header
-
-This chapter describes the details of how the file-sharing service works. As
-with all services, it is split into an API (libgnunetfs), the service process
-(gnunet-service-fs) and user interface(s). The file-sharing service uses the
-datastore service to store blocks and the DHT (and indirectly datacache) for
-lookups for non-anonymous file-sharing.@ Furthermore, the file-sharing service
-uses the block library (and the block fs plugin) for validation of DHT
-operations.
-
-In contrast to many other services, libgnunetfs is rather complex since the
-client library includes a large number of high-level abstractions; this is
-necessary since the Fs service itself largely only operates on the block level.
-The FS library is responsible for providing a file-based abstraction to
-applications, including directories, meta data, keyword search, verification,
-and so on.
-
-The method used by GNUnet to break large files into blocks and to use keyword
-search is called the "Encoding for Censorship Resistant Sharing" (ECRS). ECRS
-is largely implemented in the fs library; block validation is also reflected in
-the block FS plugin and the FS service. ECRS on-demand encoding is implemented
-in the FS service.
-
-NOTE: The documentation in this chapter is quite incomplete.
-
-@menu
-* Encoding for Censorship-Resistant Sharing (ECRS)::
-* File-sharing persistence directory structure::
-@end menu
-
-@node Encoding for Censorship-Resistant Sharing (ECRS)
-@subsection Encoding for Censorship-Resistant Sharing (ECRS)
-
-@c %**end of header
-
-When GNUnet shares files, it uses a content encoding that is called ECRS, the
-Encoding for Censorship-Resistant Sharing. Most of ECRS is described in the
-(so far unpublished) research paper attached to this page. ECRS obsoletes the
-previous ESED and ESED II encodings which were used in GNUnet before version
-0.7.0.@ @ The rest of this page assumes that the reader is familiar with the
-attached paper. What follows is a description of some minor extensions that
-GNUnet makes over what is described in the paper. The reason why these
-extensions are not in the paper is that we felt that they were obvious or
-trivial extensions to the original scheme and thus did not warrant space in
-the research report.
-
-
-@menu
-* Namespace Advertisements::
-* KSBlocks::
-@end menu
-
-@node Namespace Advertisements
-@subsubsection Namespace Advertisements
-
-@c %**end of header
-@c %**FIXME: all zeroses -> ?
-
-An @code{SBlock} with identifier all zeros is a signed
-advertisement for a namespace. This special @code{SBlock} contains metadata
-describing the content of the namespace. Instead of the name of the identifier
-for a potential update, it contains the identifier for the root of the
-namespace. The URI should always be empty. The @code{SBlock} is signed with
-the content provder's RSA private key (just like any other SBlock). Peers
-can search for @code{SBlock}s in order to find out more about a namespace.
-
-@node KSBlocks
-@subsubsection KSBlocks
-
-@c %**end of header
-
-GNUnet implements @code{KSBlocks} which are @code{KBlocks} that, instead of
-encrypting a CHK and metadata, encrypt an @code{SBlock} instead. In other
-words, @code{KSBlocks} enable GNUnet to find @code{SBlocks} using the global
-keyword search. Usually the encrypted @code{SBlock} is a namespace
-advertisement. The rationale behind @code{KSBlock}s and @code{SBlock}s is to
-enable peers to discover namespaces via keyword searches, and, to associate
-useful information with namespaces. When GNUnet finds @code{KSBlocks} during a
-normal keyword search, it adds the information to an internal list of
-discovered namespaces. Users looking for interesting namespaces can then
-inspect this list, reducing the need for out-of-band discovery of namespaces.
-Naturally, namespaces (or more specifically, namespace advertisements) can
-also be referenced from directories, but @code{KSBlock}s should make it easier
-to advertise namespaces for the owner of the pseudonym since they eliminate
-the need to first create a directory.
-
-Collections are also advertised using @code{KSBlock}s.
-
-@table @asis
-@item Attachment Size
-@item ecrs.pdf 270.68 KB
-@item https://gnunet.org/sites/default/files/ecrs.pdf
-@end table
-
-@node File-sharing persistence directory structure
-@subsection File-sharing persistence directory structure
-
-@c %**end of header
-
-This section documents how the file-sharing library implements persistence of
-file-sharing operations and specifically the resulting directory structure.
-This code is only active if the @code{GNUNET_FS_FLAGS_PERSISTENCE} flag was set
-when calling @code{GNUNET_FS_start}. In this case, the file-sharing library
-will try hard to ensure that all major operations (searching, downloading,
-publishing, unindexing) are persistent, that is, can live longer than the
-process itself. More specifically, an operation is supposed to live until it is
-explicitly stopped.
-
-If @code{GNUNET_FS_stop} is called before an operation has been stopped, a
-@code{SUSPEND} event is generated and then when the process calls
-@code{GNUNET_FS_start} next time, a @code{RESUME} event is generated.
-Additionally, even if an application crashes (segfault, SIGKILL, system crash)
-and hence @code{GNUNET_FS_stop} is never called and no @code{SUSPEND} events
-are generated, operations are still resumed (with @code{RESUME} events). This
-is implemented by constantly writing the current state of the file-sharing
-operations to disk. Specifically, the current state is always written to disk
-whenever anything significant changes (the exception are block-wise progress in
-publishing and unindexing, since those operations would be slowed down
-significantly and can be resumed cheaply even without detailed accounting).
-Note that@ if the process crashes (or is killed) during a serialization
-operation, FS does not guarantee that this specific operation is recoverable
-(no strict transactional semantics, again for performance reasons). However,
-all other unrelated operations should resume nicely.
-
-Since we need to serialize the state continuously and want to recover as much
-as possible even after crashing during a serialization operation, we do not use
-one large file for serialization. Instead, several directories are used for the
-various operations. When @code{GNUNET_FS_start} executes, the master
-directories are scanned for files describing operations to resume. Sometimes,
-these operations can refer to related operations in child directories which may
-also be resumed at this point. Note that corrupted files are cleaned up
-automatically. However, dangling files in child directories (those that are not
-referenced by files from the master directories) are not automatically removed.
-
-Persistence data is kept in a directory that begins with the "STATE_DIR" prefix
-from the configuration file (by default, "$SERVICEHOME/persistence/") followed
-by the name of the client as given to @code{GNUNET_FS_start} (for example,
-"gnunet-gtk") followed by the actual name of the master or child directory.
-
-The names for the master directories follow the names of the operations:
-
-@itemize @bullet
-@item "search"
-@item "download"
-@item "publish"
-@item "unindex"
-@end itemize
-
-Each of the master directories contains names (chosen at random) for each
-active top-level (master) operation.
-Note that a download that is associated with a search result is not a
-top-level operation.
-
-In contrast to the master directories, the child directories are only
-consulted when another operation refers to them.
-For each search, a subdirectory (named after the master search
-synchronization file) contains the search results.
-Search results can have an associated download, which is then stored in
-the general "download-child" directory.
-Downloads can be recursive, in which case children are stored in
-subdirectories mirroring the structure of the recursive download
-(either starting in the master "download" directory or in the
-"download-child" directory depending on how the download was initiated).
-For publishing operations, the "publish-file" directory contains
-information about the individual files and directories that are part of
-the publication.
-However, this directory structure is flat and does not mirror the
-structure of the publishing operation.
-Note that unindex operations cannot have associated child operations.
-
-@cindex REGEX subsystem
-@cindex regex subsystem
-@node GNUnet's REGEX Subsystem
-@section GNUnet's REGEX Subsystem
-
-@c %**end of header
-
-Using the REGEX subsystem, you can discover peers that offer a particular
-service using regular expressions.
-The peers that offer a service specify it using a regular expressions.
-Peers that want to patronize a service search using a string.
-The REGEX subsystem will then use the DHT to return a set of matching
-offerers to the patrons.
-
-For the technical details, we have Max's defense talk and Max's Master's
-thesis.
-
-@c An additional publication is under preparation and available to
-@c team members (in Git).
-@c FIXME: Where is the file? Point to it. Assuming that it's szengel2012ms
-
-@menu
-* How to run the regex profiler::
-@end menu
-
-@node How to run the regex profiler
-@subsection How to run the regex profiler
-
-@c %**end of header
-
-The gnunet-regex-profiler can be used to profile the usage of mesh/regex
-for a given set of regular expressions and strings.
-Mesh/regex allows you to announce your peer ID under a certain regex and
-search for peers matching a particular regex using a string.
-See @uref{https://gnunet.org/szengel2012ms, szengel2012ms} for a full
-introduction.
-
-First of all, the regex profiler uses GNUnet testbed, thus all the
-implications for testbed also apply to the regex profiler
-(for example you need password-less ssh login to the machines listed in
-your hosts file).
-
-@strong{Configuration}
-
-Moreover, an appropriate configuration file is needed.
-Generally you can refer to the
-@file{contrib/regex_profiler_infiniband.conf} file in the sourcecode
-of GNUnet for an example configuration.
-In the following paragraph the important details are highlighted.
-
-Announcing of the regular expressions is done by the
-gnunet-daemon-regexprofiler, therefore you have to make sure it is
-started, by adding it to the AUTOSTART set of ARM:
-
-@example
-[regexprofiler]
-AUTOSTART = YES
-@end example
-
-@noindent
-Furthermore you have to specify the location of the binary:
-
-@example
-[regexprofiler]
-# Location of the gnunet-daemon-regexprofiler binary.
-BINARY = /home/szengel/gnunet/src/mesh/.libs/gnunet-daemon-regexprofiler
-# Regex prefix that will be applied to all regular expressions and
-# search string.
-REGEX_PREFIX = "GNVPN-0001-PAD"
-@end example
-
-@noindent
-When running the profiler with a large scale deployment, you probably
-want to reduce the workload of each peer.
-Use the following options to do this.
-
-@example
-[dht]
-# Force network size estimation
-FORCE_NSE = 1
-
-[dhtcache]
-DATABASE = heap
-# Disable RC-file for Bloom filter? (for benchmarking with limited IO
-# availability)
-DISABLE_BF_RC = YES
-# Disable Bloom filter entirely
-DISABLE_BF = YES
-
-[nse]
-# Minimize proof-of-work CPU consumption by NSE
-WORKBITS = 1
-@end example
-
-@noindent
-@strong{Options}
-
-To finally run the profiler some options and the input data need to be
-specified on the command line.
-
-@example
-gnunet-regex-profiler -c config-file -d log-file -n num-links \
--p path-compression-length -s search-delay -t matching-timeout \
--a num-search-strings hosts-file policy-dir search-strings-file
-@end example
-
-@noindent
-Where...
-
-@itemize @bullet
-@item ... @code{config-file} means the configuration file created earlier.
-@item ... @code{log-file} is the file where to write statistics output.
-@item ... @code{num-links} indicates the number of random links between
-started peers.
-@item ... @code{path-compression-length} is the maximum path compression
-length in the DFA.
-@item ... @code{search-delay} time to wait between peers finished linking
-and starting to match strings.
-@item ... @code{matching-timeout} timeout after which to cancel the
-searching.
-@item ... @code{num-search-strings} number of strings in the
-search-strings-file.
-@item ... the @code{hosts-file} should contain a list of hosts for the
-testbed, one per line in the following format:
-
-@itemize @bullet
-@item @code{user@@host_ip:port}
-@end itemize
-@item ... the @code{policy-dir} is a folder containing text files
-containing one or more regular expressions. A peer is started for each
-file in that folder and the regular expressions in the corresponding file
-are announced by this peer.
-@item ... the @code{search-strings-file} is a text file containing search
-strings, one in each line.
-@end itemize
-
-@noindent
-You can create regular expressions and search strings for every AS in the
-Internet using the attached scripts. You need one of the
-@uref{http://data.caida.org/datasets/routing/routeviews-prefix2as/, CAIDA
-routeviews prefix2as} data files for this. Run
-
-@example
-create_regex.py <filename> <output path>
-@end example
-
-@noindent
-to create the regular expressions and
-
-@example
-create_strings.py <input path> <outfile>
-@end example
-
-@noindent
-to create a search strings file from the previously created
-regular expressions.
+++ /dev/null
-@node GNUnet Installation Handbook
-@chapter GNUnet Installation Handbook
-
-This handbook describes how to install (build setup, compilation) and
-setup (configuration, start) GNUnet 0.10.x. After following these
-instructions you should be able to install and then start user-interfaces
-to interact with the network.
-
-This manual is far from complete, and we welcome informed contributions,
-be it in the form of new chapters or insightful comments.
-
-@menu
-* Dependencies::
-* Pre-installation notes::
-* Generic installation instructions::
-* Build instructions for Ubuntu 12.04 using Git::
-* Build Instructions for Microsoft Windows Platforms::
-* Build instructions for Debian 7.5::
-* Installing GNUnet from Git on Ubuntu 14.4::
-* Build instructions for Debian 8::
-* Outdated build instructions for previous revisions::
-* Portable GNUnet::
-* The graphical configuration interface::
-* How to start and stop a GNUnet peer::
-@end menu
-
-@node Dependencies
-@section Dependencies
-@c %**end of header
-
-This section lists the various known dependencies for
-GNUnet @value{EDITION}.
-Suggestions for missing dependencies or wrong version numbers are welcome.
-
-@menu
-* External dependencies::
-* Fixing libgnurl build issues::
-* Optional dependencies::
-* Internal dependencies::
-@end menu
-
-@node External dependencies
-@subsection External dependencies
-@c %**end of header
-
-These packages must be installed before a typical GNUnet installation
-can be performed:
-
-@itemize @bullet
-@item autoconf
-@item automake
-@item pkg-config
-@item libltdl
-@item gstreamer
-@item gst-plugins-base
-@item perl
-@item python (only 2.7 supported)@footnote{tests and gnunet-qr}
-@item jansson
-@item nss
-@item glib
-@item gmp
-@item bluez
-@item miniupnpc
-@item gettext
-@item which
-@item texinfo
-@item GNU libmicrohttpd @geq{} 0.9.30 @footnote{We recommend to build it
-with a GnuTLS version that was configured with libunbound ("DANE support")}
-@item GNU libextractor @geq{} 1.0
-@item GNU libtool @geq{} 2.2
-@item GNU libunistring @geq{} 0.9.1.1
-@item GNU libidn @geq{} 1.0.0
-@item @uref{https://gnupg.org/software/libgcrypt/, GNU libgcrypt} @geq{}
-@uref{https://gnupg.org/ftp/gcrypt/libgcrypt/, 1.6.0}
-@item @uref{https://gnutls.org/, GnuTLS} @geq{} 3.2.7
-@footnote{We recommend to compile with libunbound for DANE support;
-GnuTLS also requires GNU nettle 2.7 (update: GnuTLS 3.2.7 appears NOT
-to work against GNU nettle > 2.7, due to some API updatings done by
-nettle. Thus it should be compiled against nettle 2.7
-and, in case you get some error on the reference to `rpl_strerror' being
-undefined, follow the instructions on
-@uref{http://lists.gnupg.org/pipermail/gnutls-devel/2013-November/006588.html, this}
-post (and the link inside it)).}
-@item @uref{https://gnunet.org/gnurl, gnURL} libgnurl @geq{} 7.34.0
-@footnote{must be compiled after @code{GnuTLS}}
-@item libglpk @geq{} 4.45
-@item @uref{http://www.openssl.org/, OpenSSL} @geq{} 1.0
-@item TeX Live @geq{} 2012, optional (for gnunet-bcd)
-@item Texinfo @geq{} 5.2 (for documentation)
-@item libsqlite @geq{} 3.8.0 @footnote{(note that the code will
-compile and often work with lower version numbers, but you may get subtle
-bugs with respect to quota management in certain rare cases);
-alternatively, MySQL or Postgres can also be installed, but those
-databases will require more complex configurations (not
-recommended for first-time users)}
-@item zlib
-@end itemize
-
-@node Fixing libgnurl build issues
-@subsection Fixing libgnurl build issues
-
-If you have to compile libgnurl from source since the version included in
-your distribution is to old you perhaps get an error message while
-running the @file{configure} script:
-
-@example
-$ configure
-...
-checking for 64-bit curl_off_t data type... unknown
-checking for 32-bit curl_off_t data type... unknown
-checking for 16-bit curl_off_t data type... unknown
-configure: error: cannot find data type for curl_off_t.
-@end example
-
-@noindent
-Solution:
-
-Before running the configure script, set:
-
-@example
-CFLAGS="-I. -I$BUILD_ROOT/include"
-@end example
-
-@node Optional dependencies
-@subsection Optional dependencies
-
-These applications must be installed for various experimental or otherwise
-optional features such as @code{gnunet-conversation}, @code{gnunet-gtk}.
-
-@itemize @bullet
-@item libpulse 2.0 or higher, optional (for gnunet-conversation)
-@item libopus 1.0.1 or higher, optional (for gnunet-conversation)
-@item libogg 1.3.0 or higher, optional (for gnunet-conversation)
-@item certool (binary) optional @footnote{for convenient installation of
-the GNS proxy (available as part of Debian's libnss3-tools)}
-@item python-zbar 0.10 or higher, optional (for gnunet-qr)
-@item Gtk+ 3.0 or higher, optional (for gnunet-gtk)
-@item libgladeui must match Gtk+ version, optional (for gnunet-gtk)
-@item libqrencode 3.0 or higher, optional (for gnunet-namestore-gtk)
-@end itemize
-
-@node Internal dependencies
-@subsection Internal dependencies
-
-This section tries to give an overview of what processes a typical GNUnet peer
-running a particular application would consist of. All of the processes listed
-here should be automatically started by @code{gnunet-arm -s}. The list is given
-as a rough first guide to users for failure diagnostics. Ideally, end-users
-should never have to worry about these internal dependencies.
-
-In terms of internal dependencies, a minimum file-sharing system consists of
-the following GNUnet processes (in order of dependency):
-
-@itemize @bullet
-@item gnunet-service-arm
-@item gnunet-service-resolver (required by all)
-@item gnunet-service-statistics (required by all)
-@item gnunet-service-peerinfo
-@item gnunet-service-transport (requires peerinfo)
-@item gnunet-service-core (requires transport)
-@item gnunet-daemon-hostlist (requires core)
-@item gnunet-daemon-topology (requires hostlist, peerinfo)
-@item gnunet-service-datastore
-@item gnunet-service-dht (requires core)
-@item gnunet-service-identity
-@item gnunet-service-fs (requires identity, mesh, dht, datastore, core)
-@end itemize
-
-
-A minimum VPN system consists of the following GNUnet processes (in order of
-dependency):
-
-@itemize @bullet
-@item gnunet-service-arm
-@item gnunet-service-resolver (required by all)
-@item gnunet-service-statistics (required by all)
-@item gnunet-service-peerinfo
-@item gnunet-service-transport (requires peerinfo)
-@item gnunet-service-core (requires transport)
-@item gnunet-daemon-hostlist (requires core)
-@item gnunet-service-dht (requires core)
-@item gnunet-service-mesh (requires dht, core)
-@item gnunet-service-dns (requires dht)
-@item gnunet-service-regex (requires dht)
-@item gnunet-service-vpn (requires regex, dns, mesh, dht)
-@end itemize
-
-
-A minimum GNS system consists of the following GNUnet processes (in order of
-dependency):
-@itemize @bullet
-@item gnunet-service-arm
-@item gnunet-service-resolver (required by all)
-@item gnunet-service-statistics (required by all)
-@item gnunet-service-peerinfo
-@item gnunet-service-transport (requires peerinfo)
-@item gnunet-service-core (requires transport)
-@item gnunet-daemon-hostlist (requires core)
-@item gnunet-service-dht (requires core)
-@item gnunet-service-mesh (requires dht, core)
-@item gnunet-service-dns (requires dht)
-@item gnunet-service-regex (requires dht)
-@item gnunet-service-vpn (requires regex, dns, mesh, dht)
-@item gnunet-service-identity
-@item gnunet-service-namestore (requires identity)
-@item gnunet-service-gns (requires vpn, dns, dht, namestore, identity)
-@end itemize
-
-@node Pre-installation notes
-@section Pre-installation notes
-
-Please note that in the code instructions for the installation,
-@emph{#} indicates commands run as privileged root user and
-@emph{$} shows commands run as unprivileged ("normal") system user.
-
-
-@node Generic installation instructions
-@section Generic installation instructions
-
-First, in addition to the GNUnet sources you must download the latest version
-of various dependencies. Most distributions do not include sufficiently recent
-versions of these dependencies. Thus, a typically installation on a "modern"
-GNU/Linux distribution requires you to install the following
-dependencies (ideally in this order):
-
-@itemize @bullet
-@item libgpgerror and libgcrypt
-@item libnettle and libunbound (possibly from distribution), GnuTLS
-@item libgnurl (read the README)
-@item GNU libmicrohttpd
-@item GNU libextractor
-@end itemize
-
-Make sure to first install the various mandatory and optional
-dependencies including development headers from your distribution.
-
-Other dependencies that you should strongly consider to install is a
-database (MySQL, sqlite or Postgres). The following instructions will assume
-that you installed at least sqlite. For most distributions you should be able
-to find pre-build packages for the database. Again, make sure to install the
-client libraries and the respective development headers (if they are
-packaged separately) as well.
-
-You can find specific, detailed instructions for installing of the dependencies
-(and possibly the rest of the GNUnet installation) in the platform-specific
-descriptions, which are linked from the bottom of this page. Please consult
-them now. If your distribution is not listed, please study the instructions for
-Debian stable carefully as you try to install the dependencies for your own
-distribution. Contributing additional instructions for further platforms is
-always appreciated.
-
-Before proceeding further, please double-check the dependency list.
-Note that in addition to satisfying the dependencies, you might have to
-make sure that development headers for the various libraries are also
-installed.
-There maybe files for other distributions, or you might be able to find
-equivalent packages for your distribution.
-
-While it is possible to build and install GNUnet without having root access,
-we will assume that you have full control over your system in these
-instructions. First, you should create a system user @emph{gnunet} and
-an additional group @emph{gnunetdns}. On Debian and Ubuntu GNU/Linux, type:
-
-@example
-# adduser --system --home /var/lib/gnunet --group \
---disabled-password gnunet
-# addgroup --system gnunetdns
-@end example
-
-On other Unixes, this should have the same effect:
-
-@example
-# useradd --system --groups gnunet --home-dir /var/lib/gnunet
-# addgroup --system gnunetdns
-@end example
-
-Now compile and install GNUnet using:
-
-@example
-$ tar xvf gnunet-0.10.?.tar.gz
-$ cd gnunet-0.10.?
-$ ./configure --with-sudo=sudo --with-nssdir=/lib
-$ make
-$ sudo make install
-@end example
-
-If you want to be able to enable DEBUG-level log messages, add
-@code{--enable-logging=verbose} to the end of the @code{./configure} command.
-DEBUG-level log messages are in English-only and should only be useful for
-developers (or for filing really detailed bug reports).
-
-Finally, you probably want to compile @code{gnunet-gtk}, which
-includes gnunet-setup (graphical tool for configuration)
-and @code{gnunet-fs-gtk} (graphical tool for file-sharing):
-
-@example
-$ tar xvf gnunet-gtk-0.10.?.tar.gz
-$ cd gnunet-gtk-0.10.?
-$ ./configure --with-gnunet=/usr/local/
-$ make
-$ sudo make install
-$ cd ..
-$ sudo ldconfig # just to be safe
-@end example
-
-Next, edit the file @file{/etc/gnunet.conf} to contain the following:
-
-@example
-[arm]
-SYSTEM_ONLY = YES
-USER_ONLY = NO
-@end example
-
-You may need to update your ld.so cache to include files installed in
-@file{/usr/local/lib}: @code{ # ldconfig }.
-
-Then, switch from user root to user gnunet to start the peer:
-
-@example
-# su -s /bin/sh - gnunet
-$ gnunet-arm -c /etc/gnunet.conf -s
-@end example
-
-You may also want to add the last line in the gnunet users @file{crontab}
-prefixed with @code{@@reboot} so that it is executed whenever the system is
-booted:
-
-@example
-@@reboot /usr/local/bin/gnunet-arm -c /etc/gnunet.conf -s@
-@end example
-
-This will only start the system-wide GNUnet services. Type exit to get back
-your root shell. Now, you need to configure the per-user part. For each
-$USER on the system, run: @code{ # adduser $USER gnunet }.
-
-to allow them to access the system-wide GNUnet services. Then, each
-user should create a configuration file @file{~/.config/gnunet.conf}
-with the lines:
-
-@example
-[arm]
-SYSTEM_ONLY = NO
-USER_ONLY = YES
-DEFAULTSERVICES = gns
-@end example
-
-and start the per-user services using
-
-@code{@
- $ gnunet-arm -c ~/.config/gnunet.conf -s@
-}@
-
-Again, adding a @code{crontab} entry to autostart the peer is advised:@
-@code{@
-@@reboot /usr/local/bin/gnunet-arm -c $HOME/.config/gnunet.conf -s@
-}@
-
-Note that some GNUnet services (such as SOCKS5 proxies) may need a system-wide
-TCP port for each user. For those services, systems with more than one user may
-require each user to specify a different port number in their personal
-configuration file.
-
-Finally, the user should perform the basic initial setup for the GNU Name
-System. This is done by running two commands:@
-
-@example
-$ gnunet-gns-import.sh@
-$ gnunet-gns-proxy-setup-ca@
-@end example
-
-The first generates the default zones, wheras the second setups the GNS
-Certificate Authority with the user's browser. Now, to actiave GNS in the
-normal DNS resolution process, you need to edit your @file{/etc/nsswitch.conf}
-where you should find a line like this:
-@example
-hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4
-@end example
-
-
-The exact details may differ a bit, which is fine. Add the text
-@emph{"gns [NOTFOUND=return]"} after @emph{"files"}:
-
-@example
-hosts: files gns [NOTFOUND=return] mdns4_minimal [NOTFOUND=return] dns mdns4
-@end example
-
-
-You might want to make sure that @file{/lib/libnss_gns.so.2} exists on your
-system, it should have been created during the installation.
-
-
-
-@node Build instructions for Ubuntu 12.04 using Git
-@section Build instructions for Ubuntu 12.04 using Git
-
-
-@menu
-* Install the required build tools::
-* Install libgcrypt 1.6 and libgpg-error::
-* Install gnutls with DANE support::
-* Install libgnurl::
-* Install libmicrohttpd from Git::
-* Install libextractor from Git::
-* Install GNUnet dependencies::
-* Build GNUnet::
-* Install the GNUnet-gtk user interface from Git::
-@end menu
-
-@node Install the required build tools
-@subsection Install the required build tools
-
-First, make sure Git is installed on your system:
-
-@example
-$ sudo apt-get install git
-@end example
-
-Install the essential buildtools:
-
-@example
-$ sudo apt-get install automake autopoint autoconf libtool
-@end example
-
-@node Install libgcrypt 1.6 and libgpg-error
-@subsection Install libgcrypt 1.6 and libgpg-error
-
-@example
-$ wget ftp://ftp.gnupg.org/gcrypt/libgpg-error/libgpg-error-1.12.tar.bz2
-$ tar xf libgpg-error-1.12.tar.bz2
-$ cd libgpg-error-1.12
-$ ./configure
-$ sudo make install ; cd ..
-@end example
-
-@node Install gnutls with DANE support
-@subsection Install gnutls with DANE support
-
-@example
-$ wget http://www.lysator.liu.se/~nisse/archive/nettle-2.7.1.tar.gz
-$ tar xf nettle-2.7.1.tar.gz
-$ cd nettle-2.7.1
-$ ./configure
-$ sudo make install ; cd ..
-@end example
-
-@example
-$ wget https://www.nlnetlabs.nl/downloads/ldns/ldns-1.6.16.tar.gz
-$ tar xf ldns-1.6.16.tar.gz
-$ cd ldns-1.6.16
-$ ./configure
-$ sudo make install ; cd ..
-@end example
-
-@example
-$ wget https://unbound.net/downloads/unbound-1.4.21.tar.gz
-$ tar xf unbound-1.4.21.tar.gz
-$ cd unbound-1.4.21
-$ ./configure
-$ sudo make install ; cd ..
-@end example
-
-@example
-$ wget ftp://ftp.gnutls.org/gcrypt/gnutls/v3.1/gnutls-3.1.17.tar.xz
-$ tar xf gnutls-3.1.17.tar.xz
-$ cd gnutls-3.1.17
-$ ./configure
-$ sudo make install ; cd ..
-@end example
-
-@example
-$ wget ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.6.0.tar.bz2
-$ tar xf libgcrypt-1.6.0.tar.bz2
-$ cd libgcrypt-1.6.0
-$ ./configure
-$ sudo make install ; cd ..
-@end example
-
-@node Install libgnurl
-@subsection Install libgnurl
-
-@example
-$ wget https://gnunet.org/sites/default/files/gnurl-7.34.0.tar.bz2
-$ tar xf gnurl-7.34.0.tar.bz2
-$ cd gnurl-7.34.0
-$ ./configure --enable-ipv6 --with-gnutls --without-libssh2 \
- --without-libmetalink --without-winidn --without-librtmp \
- --without-nghttp2 --without-nss --without-cyassl \
- --without-polarssl --without-ssl --without-winssl \
- --without-darwinssl --disable-sspi --disable-ntlm-wb \
- --disable-ldap --disable-rtsp --disable-dict --disable-telnet \
- --disable-tftp --disable-pop3 --disable-imap --disable-smtp \
- --disable-gopher --disable-file --disable-ftp
-$ sudo make install ; cd ..
-@end example
-
-@node Install libmicrohttpd from Git
-@subsection Install libmicrohttpd from Git
-
-@example
-$ git clone https://gnunet.org/git/libmicrohttpd
-$ cd libmicrohttpd/
-$ ./bootstrap
-$ ./configure
-$ sudo make install ; cd ..
-@end example
-
-@node Install libextractor from Git
-@subsection Install libextractor from Git
-
-Install libextractor dependencies:
-
-@example
-$ sudo apt-get install zlib1g-dev libgsf-1-dev libmpeg2-4-dev \
- libpoppler-dev libvorbis-dev libexiv2-dev libjpeg-dev \
- libtiff-dev libgif-dev libvorbis-dev libflac-dev libsmf-dev \
- g++
-@end example
-
-Build libextractor:
-
-@example
-$ git clone https://gnunet.org/git/libextractor
-$ cd libextractor
-$ ./bootstrap
-$ ./configure
-$ sudo make install ; cd ..
-@end example
-
-@node Install GNUnet dependencies
-@subsection Install GNUnet dependencies
-
-@example
-$ sudo apt-get install libidn11-dev libunistring-dev libglpk-dev \
- libpulse-dev libbluetooth-dev libsqlite-dev
-@end example
-
-Install libopus:
-
-@example
-$ wget http://downloads.xiph.org/releases/opus/opus-1.1.tar.gz
-$ tar xf opus-1.1.tar.gz
-$ cd opus-1.1/
-$ ./configure
-$ sudo make install ; cd ..
-@end example
-
-Choose one or more database backends:
-
-SQLite3:
-@example
-$ sudo apt-get install libsqlite3-dev
-@end example
-MySQL:
-@example
-$ sudo apt-get install libmysqlclient-dev
-@end example
-PostgreSQL:
-@example
-$ sudo apt-get install libpq-dev postgresql
-@end example
-
-
-
-@node Build GNUnet
-@subsection Build GNUnet
-
-
-
-@menu
-* Configuring the installation path::
-* Configuring the system::
-* Installing components requiring sudo permission::
-* Build::
-@end menu
-
-@node Configuring the installation path
-@subsubsection Configuring the installation path
-
-You can specify the location of the GNUnet installation by setting the prefix
-when calling the configure script with @code{--prefix=DIRECTORY}
-
-@example
-$ export PATH=$PATH:DIRECTORY/bin
-@end example
-
-@node Configuring the system
-@subsubsection Configuring the system
-
-Please make sure NOW that you have created a user and group 'gnunet'
-and additionally a group 'gnunetdns':
-
-@example
-$ sudo addgroup gnunet
-$ sudo addgroup gnunetdns
-$ sudo adduser gnunet
-@end example
-
-Each GNUnet user should be added to the 'gnunet' group (may
-require fresh login to come into effect):
-
-@example
-$ sudo useradd -G gnunet
-@end example
-
-@node Installing components requiring sudo permission
-@subsubsection Installing components requiring sudo permission
-
-Some components, like the nss plugin required for GNS, may require root
-permissions. To allow these few components to be installed use:
-
-@example
-$ ./configure --with-sudo
-@end example
-
-@node Build
-@subsubsection Build
-
-@example
-$ git clone https://gnunet.org/git/gnunet/
-$ cd gnunet/
-$ ./bootstrap
-@end example
-
-Use the required configure call including the optional installation prefix
-PREFIX or the sudo permissions:
-
-@example
-$ ./configure [ --with-sudo | --with-prefix=PREFIX ]
-@end example
-
-@example
-$ make; sudo make install
-@end example
-
-After installing it, you need to create an empty configuration file:
-
-@example
-mkdir ~/.gnunet; touch ~/.gnunet/gnunet.conf
-@end example
-
-And finally you can start GNUnet with @code{$ gnunet-arm -s}.
-
-@node Install the GNUnet-gtk user interface from Git
-@subsection Install the GNUnet-gtk user interface from Git
-
-
-Install depencies:
-
-@example
-$ sudo apt-get install libgtk-3-dev libunique-3.0-dev libgladeui-dev \
-libqrencode-dev
-@end example
-
-To build GNUnet (with an optional prefix)and execute:
-
-@example
-$ git clone https://gnunet.org/git/gnunet-gtk/
-$ cd gnunet-gtk/
-$ ./bootstrap
-$ ./configure [--prefix=PREFIX] --with-gnunet=DIRECTORY
-$ make; sudo make install
-@end example
-
-@node Build Instructions for Microsoft Windows Platforms
-@section Build Instructions for Microsoft Windows Platforms
-
-@menu
-* Introduction to building on MS Windows::
-* Requirements::
-* Dependencies & Initial Setup::
-* GNUnet Installation::
-* Adjusting Windows for running and testing GNUnet::
-* Building the GNUnet Installer::
-* Using GNUnet with Netbeans on Windows::
-@end menu
-
-@node Introduction to building on MS Windows
-@subsection Introduction to building on MS Windows
-
-
-This document is a guide to building GNUnet and its dependencies on Windows
-platforms. GNUnet development is mostly done under Linux and especially SVN
-checkouts may not build out of the box. We regret any inconvenience, and
-if you have problems, please report them.
-
-@node Requirements
-@subsection Requirements
-
-The Howto is based upon a @strong{Windows Server 2008 32bit@strong{
-Installation, @strong{sbuild} and thus a @uref{http://www.mingw.org/wiki/MSYS,
-MSYS+MinGW} (W32-GCC-Compiler-Suite + Unix-like Userland) installation. sbuild
-is a convenient set of scripts which creates a working msys/mingw installation
-and installs most dependencies required for GNUnet. }}
-
-As of the point of the creation of this Howto, GNUnet @strong{requires} a
-Windows @strong{Server} 2003 or newer for full feature support. Windows Vista
-and later will also work, but
-@strong{non-server version can not run a VPN-Exit-Node} as the NAT features
-have been removed as of Windows Vista.
-
-@node Dependencies & Initial Setup
-@subsection Dependencies & Initial Setup
-
-
-@itemize @bullet
-
-@item
-Install a fresh version of @strong{Python 2.x}, even if you are using a x64-OS,
-install a 32-bit version for use with sbuild. Python 3.0 currently is
-incompatible.
-
-@item
-Install your favorite @uref{http://code.google.com/p/tortoisegit/, GIT} &
-@uref{http://tortoisesvn.net/, SVN}-clients.
-
-@item
-You will also need some archive-manager like @uref{http://www.7-zip.org/, 7zip}.
-
-@item
-Pull a copy of sbuild to a directory of your choice, which will be used in the
-remainder of this guide. For now, we will use @file{c:\gnunet\sbuild\}
-
-@item
-in @file{sbuild\src\mingw\mingw32-buildall.sh}, comment out the packages
-@strong{gnunet-svn} and @strong{gnunet-gtk-svn}, as we don't want sbuild to
-compile/install those for us.
-
-@item
-Follow LRN's sbuild installation instructions.-
-@end itemize
-
-Please note that sbuild may (or will most likely) fail during installation,
-thus you really HAVE to @strong{check the logfiles} created during the
-installation process. Certain packages may fail to build initially due to
-missing dependencies, thus you may have to
-@strong{substitute those with binary-versions initially}. Later on once
-dependencies are satisfied you can re-build the newer package versions.
-
-@strong{It is normal that you may have to repeat this step multiple times and
-there is no uniform way to fix all compile-time issues, as the build-process
-of many of the dependencies installed are rather unstable on win32 and certain
-releases may not even compile at all.}
-
-Most dependencies for GNUnet have been set up by sbuild, thus we now should add
-the @file{bin/} directories in your new msys and mingw installations to PATH.
-You will want to create a backup of your finished msys-environment by now.
-
-@node GNUnet Installation
-@subsection GNUnet Installation
-
-First, we need to launch our msys-shell, you can do this via
-
-@file{C:\gnunet\sbuild\msys\msys.bat}
-
-You might wish to take a look at this file and adjust some login-parameters to
-your msys environment.
-
-Also, sbuild added two pointpoints to your msys-environment, though those
-might remain invisible:
-
-@itemize @bullet
-
-@item
-/mingw, which will mount your mingw-directory from sbuild/mingw and the other one is
-
-@item
-/src which contains all the installation sources sbuild just compiled.
-@end itemize
-
-Check out the current gnunet-sources (svn-head) from the gnunet-repository,
-we will do this in your home directory:
-
-@code{svn checkout https://gnunet.org/svn/gnunet/ ~/gnunet}
-
-Now, we will first need to bootstrap the checked out installation and then
-configure it accordingly.
-
-@example
-cd ~/gnunet
-./bootstrap
-STRIP=true CPPFLAGS="-DUSE_IPV6=1 -DW32_VEH" CFLAGS="$CFLAGS -g -O2" \
-./configure --prefix=/ --docdir=/share/doc/gnunet \
---with-libiconv-prefix=/mingw --with-libintl-prefix=/mingw \
---with-libcurl=/mingw --with-extractor=/mingw --with-sqlite=/mingw \
---with-microhttpd=/mingw --with-plibc=/mingw --enable-benchmarks \
---enable-expensivetests --enable-experimental --with-qrencode=/mingw \
---enable-silent-rules --enable-experimental 2>&1 | tee -a ./configure.log
-@end example
-
-The parameters above will configure for a reasonable gnunet installation to the
-your msys-root directory. Depending on which features your would like to build
-or you may need to specify additional dependencies. Sbuild installed most libs
-into the /mingw subdirectory, so remember to prefix library locations with
-this path.
-
-Like on a unixoid system, you might want to use your home directory as prefix
-for your own gnunet installation for development, without tainting the
-buildenvironment. Just change the "prefix" parameter to point towards
-~/ in this case.
-
-Now it's time to compile gnunet as usual. Though this will take some time, so
-you may fetch yourself a coffee or some Mate now...
-
-@example
-make ; make install
-@end example
-
-@node Adjusting Windows for running and testing GNUnet
-@subsection Adjusting Windows for running and testing GNUnet
-
-Assuming the build succeeded and you
-@strong{added the bin directory of your gnunet to PATH}, you can now use your
-gnunet-installation as usual. Remember that UAC or the windows firewall may
-popup initially, blocking further execution of gnunet until you acknowledge
-them (duh!).
-
-You will also have to take the usual steps to get p2p software running properly
-(port forwarding, ...), and gnunet will require administrative permissions as
-it may even install a device-driver (in case you are using gnunet-vpn and/or
-gnunet-exit).
-
-@node Building the GNUnet Installer
-@subsection Building the GNUnet Installer
-
-The GNUnet installer is made with @uref{http://nsis.sourceforge.net/, NSIS}
-The installer script is located in @file{contrib\win} in the
-GNUnet source tree.
-
-@node Using GNUnet with Netbeans on Windows
-@subsection Using GNUnet with Netbeans on Windows
-
-TODO
-
-@node Build instructions for Debian 7.5
-@section Build instructions for Debian 7.5
-
-
-These are the installation instructions for Debian 7.5. They were tested using
-a minimal, fresh Debian 7.5 AMD64 installation without non-free software
-(no contrib or non-free). By "minimal", we mean that during installation, we
-did not select any desktop environment, servers or system utilities during the
-"tasksel" step. Note that the packages and the dependencies that we will
-install during this chapter take about 1.5 GB of disk space. Combined with
-GNUnet and space for objects during compilation, you should not even attempt
-this unless you have about 2.5 GB free after the minimal Debian installation.
-Using these instructions to build a VM image is likely to require a minimum of
-4-5 GB for the VM (as you will likely also want a desktop manager).
-
-GNUnet's security model assumes that your @file{/home} directory is encrypted.
-Thus, if possible, you should encrypt your home partition
-(or per-user home directory).
-
-Naturally, the exact details of the starting state for your installation
-should not matter much. For example, if you selected any of those installation
-groups you might simply already have some of the necessary packages installed.
-We did this for testing, as this way we are less likely to forget to mention a
-required package. Note that we will not install a desktop environment, but of
-course you will need to install one to use GNUnet's graphical user interfaces.
-Thus, it is suggested that you simply install the desktop environment of your
-choice before beginning with the instructions.
-
-
-
-@menu
-* Update::
-* Stable? Hah!::
-* Update again::
-* Installing packages::
-* Installing dependencies from source::
-* Installing GNUnet from source::
-* But wait there is more!::
-@end menu
-
-@node Update
-@subsection Update
-
-After any installation, you should begin by running
-
-@example
-# apt-get update ; apt-get upgrade
-@end example
-
-to ensure that all of your packages are up-to-date. Note that the "#" is used
-to indicate that you need to type in this command as "root"
-(or prefix with "sudo"), whereas "$" is used to indicate typing in a command
-as a normal user.
-
-@node Stable? Hah!
-@subsection Stable? Hah!
-
-Yes, we said we start with a Debian 7.5 "stable" system. However, to reduce the
-amount of compilation by hand, we will begin by allowing the installation of
-packages from the testing and unstable distributions as well. We will stick to
-"stable" packages where possible, but some packages will be taken from the
-other distributions. Start by modifying @file{/etc/apt/sources.list} to contain
-the following (possibly adjusted to point to your mirror of choice):
-@example
-# These were there before:
-deb http://ftp.de.debian.org/debian/ wheezy main
-deb-src http://ftp.de.debian.org/debian/ wheezy main
-deb http://security.debian.org/ wheezy/updates main
-deb-src http://security.debian.org/ wheezy/updates main
-deb http://ftp.de.debian.org/debian/ wheezy-updates main
-deb-src http://ftp.de.debian.org/debian/ wheezy-updates main
-
-# Add these lines (feel free to adjust the mirror):
-deb http://ftp.de.debian.org/debian/ testing main
-deb http://ftp.de.debian.org/debian/ unstable main
-@end example
-
-The next step is to create/edit your @file{/etc/apt/preferences} file to look
-like this:
-
-@example
-Package: *
-Pin: release a=stable,n=wheezy
-Pin-Priority: 700
-
-Package: *
-Pin: release o=Debian,a=testing
-Pin-Priority: 650
-
-Package: *
-Pin: release o=Debian,a=unstable
-Pin-Priority: 600
-@end example
-
-You can read more about Apt Preferences here and here. Note that other pinnings
-are likely to also work for GNUnet, the key thing is that you need some
-packages from unstable (as shown below). However, as unstable is unlikely to
-be comprehensive (missing packages) or might be problematic (crashing packages),
-you probably want others from stable and/or testing.
-
-@node Update again
-@subsection Update again
-
-Now, run again@
-
-@example
-# apt-get update@
-# apt-get upgrade@
-@end example
-
-to ensure that all your new distribution indices are downloaded, and that your
-pinning is correct: the upgrade step should cause no changes at all.
-
-@node Installing packages
-@subsection Installing packages
-
-We begin by installing a few Debian packages from stable:@
-
-@example
-# apt-get install gcc make python-zbar libltdl-dev libsqlite3-dev \
- libunistring-dev libopus-dev libpulse-dev openssl libglpk-dev \
- texlive libidn11-dev libmysqlclient-dev libpq-dev libarchive-dev \
- libbz2-dev libexiv2-dev libflac-dev libgif-dev libglib2.0-dev \
- libgtk-3-dev libmagic-dev libjpeg8-dev libmpeg2-4-dev libmp4v2-dev \
- librpm-dev libsmf-dev libtidy-dev libtiff5-dev libvorbis-dev \
- libogg-dev zlib1g-dev g++ gettext libgsf-1-dev libunbound-dev \
- libqrencode-dev libgladeui-dev nasm texlive-latex-extra \
- libunique-3.0-dev gawk miniupnpc libfuse-dev libbluetooth-dev
-@end example
-
-After that, we install a few more packages from unstable:@
-
-@example
-# apt-get install -t unstable nettle-dev libgstreamer1.0-dev \
- gstreamer1.0-plugins-base gstreamer1.0-plugins-good \
- libgstreamer-plugins-base1.0-dev
-@end example
-
-@node Installing dependencies from source
-@subsection Installing dependencies from source
-
-Next, we need to install a few dependencies from source. You might want to do
-this as a "normal" user and only run the @code{make install} steps as root
-(hence the @code{sudo} in the commands below). Also, you do this from any
-directory. We begin by downloading all dependencies, then extracting the
-sources, and finally compiling and installing the libraries:@
-
-@example
-$ wget https://libav.org/releases/libav-9.10.tar.xz
-$ wget http://ftp.gnu.org/gnu/libextractor/libextractor-1.3.tar.gz
-$ wget ftp://ftp.gnupg.org/gcrypt/libgpg-error/libgpg-error-1.12.tar.bz2
-$ wget ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.6.0.tar.bz2
-$ wget ftp://ftp.gnutls.org/gcrypt/gnutls/v3.2/gnutls-3.2.7.tar.xz
-$ wget http://ftp.gnu.org/gnu/libmicrohttpd/libmicrohttpd-0.9.33.tar.gz
-$ wget https://gnunet.org/sites/default/files/gnurl-7.34.0.tar.bz2
-$ tar xvf libextractor-1.3.tar.gz
-$ tar xvf libgpg-error-1.12.tar.bz2
-$ tar xvf libgcrypt-1.6.0.tar.bz2
-$ tar xvf gnutls-3.2.7.tar.xz
-$ tar xvf libmicrohttpd-0.9.33.tar.gz
-$ tar xvf gnurl-7.34.0.tar.bz2
-$ cd libav-0.9 ; ./configure --enable-shared;
-$ make; sudo make install; cd ..
-$ cd libextractor-1.3 ; ./configure;
-$ make ; sudo make install; cd ..
-$ cd libgpg-error-1.12; ./configure;
-$ make ; sudo make install; cd ..
-$ cd libgcrypt-1.6.0; ./configure --with-gpg-error-prefix=/usr/local;
-$ make ; sudo make install ; cd ..
-$ cd gnutls-3.2.7 ; ./configure;
-$ make ; sudo make install ; cd ..
-$ cd libmicrohttpd-0.9.33; ./configure;
-$ make ; sudo make install ; cd ..
-$ cd gnurl-7.34.0
-$ ./configure --enable-ipv6 --with-gnutls=/usr/local --without-libssh2 \
- --without-libmetalink --without-winidn --without-librtmp --without-nghttp2 \
- --without-nss --without-cyassl --without-polarssl --without-ssl \
- --without-winssl --without-darwinssl --disable-sspi --disable-ntlm-wb \
- --disable-ldap --disable-rtsp --disable-dict --disable-telnet --disable-tftp \
- --disable-pop3 --disable-imap --disable-smtp --disable-gopher --disable-file \
- --disable-ftp
-$ make ; sudo make install; cd ..
-@end example
-
-@node Installing GNUnet from source
-@subsection Installing GNUnet from source
-
-
-For this, simply follow the generic installation instructions from
-here.
-
-@node But wait there is more!
-@subsection But wait there is more!
-
-So far, we installed all of the packages and dependencies required to ensure
-that all of GNUnet would be built. However, while for example the plugins to
-interact with the MySQL or Postgres databases have been created, we did not
-actually install or configure those databases. Thus, you will need to install
-and configure those databases or stick with the default Sqlite database.
-Sqlite is usually fine for most applications, but MySQL can offer better
-performance and Postgres better resillience.
-
-
-@node Installing GNUnet from Git on Ubuntu 14.4
-@section Installing GNUnet from Git on Ubuntu 14.4
-
-@strong{Install the required build tools:}
-@code{ $ sudo apt-get install git automake autopoint autoconf }
-
-@strong{Install the required dependencies}
-@example
-$ sudo apt-get install libltdl-dev libgpg-error-dev libidn11-dev \
- libunistring-dev libglpk-dev libbluetooth-dev libextractor-dev \
- libmicrohttpd-dev libgnutls28-dev
-@end example
-
-@strong{Choose one or more database backends}
-
-SQLite3:
-@example
-$ sudo apt-get install libsqlite3-dev
-@end example
-MySQL:
-@example
-$ sudo apt-get install libmysqlclient-dev
-@end example
-PostgreSQL:
-@example
-$ sudo apt-get install libpq-dev postgresql
-@end example
-
-@strong{Install the optional dependencies for gnunet-conversation:}
-
-@example
-$ sudo apt-get install gstreamer1.0 libpulse-dev libopus-dev
-@end example
-
-@strong{Install the libgrypt 1.6.1:}
-For Ubuntu 14.04:
-@example
-$ sudo apt-get install libgcrypt20-dev
-@end example
-For Ubuntu older 14.04:
-@example
-$ wget ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.6.1.tar.bz2
-$ tar xf libgcrypt-1.6.1.tar.bz2
-$ cd libgcrypt-1.6.1
-$ ./configure
-$ sudo make install
-$ cd ..
-@end example
-@strong{Install libgnurl}
-@example
-$ wget https://gnunet.org/sites/default/files/gnurl-7.35.0.tar.bz2
-$ tar xf gnurl-7.35.0.tar.bz2
-$ cd gnurl-7.35.0
-$ ./configure --enable-ipv6 --with-gnutls --without-libssh2 \
- --without-libmetalink --without-winidn --without-librtmp --without-nghttp2 \
- --without-nss --without-cyassl --without-polarssl --without-ssl \
- --without-winssl --without-darwinssl --disable-sspi --disable-ntlm-wb \
- --disable-ldap --disable-rtsp --disable-dict --disable-telnet --disable-tftp \
- --disable-pop3 --disable-imap --disable-smtp --disable-gopher --disable-file \
- --disable-ftp
-$ sudo make install
-$ cd ..
-@end example
-
-@strong{Install GNUnet}
-@example
-$ git clone https://gnunet.org/git/gnunet/
-$ cd gnunet/
-$ ./bootstrap
-@end example
-
-If you want to:
-@itemize @bullet
-
-
-@item
-Install to a different directory:@
- --prefix=PREFIX
-
-@item
-Have sudo permission, but do not want to compile as root:@
- --with-sudo
-
-@item
-Want debug message enabled:@
- -- enable-logging=verbose
-@end itemize
-
-
-@code{@
- $ ./configure [ --with-sudo | --prefix=PREFIX | --- enable-logging=verbose]@
- $ make; sudo make install@
-}
-
-After installing it, you need to create an empty configuration file:@
-@code{touch ~/.config/gnunet.conf}
-
-And finally you can start GNUnet with@
-@code{$ gnunet-arm -s}
-
-@node Build instructions for Debian 8
-@section Build instructions for Debian 8
-
-These are the installation instructions for Debian 8. They were tested using a
-fresh Debian 8 AMD64 installation without non-free software (no contrib or
-non-free). During installation, I only selected "lxde" for the desktop
-environment. Note that the packages and the dependencies that we will install
-during this chapter take about 1.5 GB of disk space. Combined with GNUnet and
-space for objects during compilation, you should not even attempt this unless
-you have about 2.5 GB free after the Debian installation. Using these
-instructions to build a VM image is likely to require a minimum of 4-5 GB for
-the VM (as you will likely also want a desktop manager).
-
-GNUnet's security model assumes that your @code{/home} directory is encrypted.
-Thus, if possible, you should encrypt your entire disk, or at least just your
-home partition (or per-user home directory).
-
-Naturally, the exact details of the starting state for your installation should
-not matter much. For example, if you selected any of those installation groups
-you might simply already have some of the necessary packages installed. Thus,
-it is suggested that you simply install the desktop environment of your choice
-before beginning with the instructions.
-
-
-@menu
-* Update Debian::
-* Installing Debian Packages::
-* Installing Dependencies from Source2::
-* Installing GNUnet from Source2::
-* But wait (again) there is more!::
-@end menu
-
-@node Update Debian
-@subsection Update Debian
-
-After any installation, you should begin by running@
-@code{@
- # apt-get update@
- # apt-get upgrade@
-}@
-to ensure that all of your packages are up-to-date. Note that the "#" is used
-to indicate that you need to type in this command as "root" (or prefix with
-"sudo"), whereas "$" is used to indicate typing in a command as a normal
-user.
-
-@node Installing Debian Packages
-@subsection Installing Debian Packages
-
-We begin by installing a few Debian packages from stable:@
-@example
- # apt-get install gcc make python-zbar libltdl-dev libsqlite3-dev \
- libunistring-dev libopus-dev libpulse-dev openssl libglpk-dev texlive \
- libidn11-dev libmysqlclient-dev libpq-dev libarchive-dev libbz2-dev \
- libflac-dev libgif-dev libglib2.0-dev libgtk-3-dev libmpeg2-4-dev \
- libtidy-dev libvorbis-dev libogg-dev zlib1g-dev g++ gettext libgsf-1-dev \
- libunbound-dev libqrencode-dev libgladeui-dev nasm texlive-latex-extra \
- libunique-3.0-dev gawk miniupnpc libfuse-dev libbluetooth-dev \
- gstreamer1.0-plugins-base gstreamer1.0-plugins-good \
- libgstreamer-plugins-base1.0-dev nettle-dev libextractor-dev libgcrypt20-dev \
- libmicrohttpd-dev
-@end example
-
-@node Installing Dependencies from Source2
-@subsection Installing Dependencies from Source2
-
-Yes, we said we start with a Debian 8 "stable" system, but because Debian
-linked GnuTLS without support for DANE, we need to compile a few things, in
-addition to GNUnet, still by hand. Yes, you can run GNUnet using the respective
-Debian packages, but then you will not get DANE support.
-
-Next, we need to install a few dependencies from source. You might want to do
-this as a "normal" user and only run the @code{make install} steps as root
-(hence the @code{sudo} in the commands below). Also, you do this from any
-directory. We begin by downloading all dependencies, then extracting the
-sources, and finally compiling and installing the libraries:@
-
-@code{@
- $ wget ftp://ftp.gnutls.org/gcrypt/gnutls/v3.3/gnutls-3.3.12.tar.xz@
- $ wget https://gnunet.org/sites/default/files/gnurl-7.40.0.tar.bz2@
- $ tar xvf gnutls-3.3.12.tar.xz@
- $ tar xvf gnurl-7.40.0.tar.bz2@
- $ cd gnutls-3.3.12 ; ./configure ; make ; sudo make install ; cd ..@
- $ cd gnurl-7.40.0@
- $ ./configure --enable-ipv6 --with-gnutls=/usr/local --without-libssh2 \
- --without-libmetalink --without-winidn --without-librtmp --without-nghttp2 \
- --without-nss --without-cyassl --without-polarssl --without-ssl \
- --without-winssl --without-darwinssl --disable-sspi --disable-ntlm-wb \
- --disable-ldap --disable-rtsp --disable-dict --disable-telnet --disable-tftp \
- --disable-pop3 --disable-imap --disable-smtp --disable-gopher --disable-file \
- --disable-ftp --disable-smb
- $ make ; sudo make install; cd ..@
-}
-
-@node Installing GNUnet from Source2
-@subsection Installing GNUnet from Source2
-
-For this, simply follow the generic installation instructions from@
-here.
-
-@node But wait (again) there is more!
-@subsection But wait (again) there is more!
-
-So far, we installed all of the packages and dependencies required to ensure
-that all of GNUnet would be built. However, while for example the plugins to
-interact with the MySQL or Postgres databases have been created, we did not
-actually install or configure those databases. Thus, you will need to install
-and configure those databases or stick with the default Sqlite database. Sqlite
-is usually fine for most applications, but MySQL can offer better performance
-and Postgres better resillience.
-
-@node Outdated build instructions for previous revisions
-@section Outdated build instructions for previous revisions
-
-This chapter contains a collection of outdated, older installation guides. They
-are mostly intended to serve as a starting point for writing up-to-date
-instructions and should not be expected to work for GNUnet 0.10.x.
-A set of older installation instructions can also be found in the
-@file{doc/outdated-and-old-installation-instructions.txt} in the source
-of GNUnet. This file covers old instructions which no longer receive
-security updates or any kind of support.
-
-
-@menu
-* Installing GNUnet 0.10.1 on Ubuntu 14.04::
-* Building GLPK for MinGW::
-* GUI build instructions for Ubuntu 12.04 using Subversion::
-* Installation with gnunet-update::
-* Instructions for Microsoft Windows Platforms (Old)::
-@end menu
-
-
-@node Installing GNUnet 0.10.1 on Ubuntu 14.04
-@subsection Installing GNUnet 0.10.1 on Ubuntu 14.04
-
-Install the required dependencies@
-
-@example
-$ sudo apt-get install libltdl-dev libgpg-error-dev libidn11-dev \
- libunistring-dev libglpk-dev libbluetooth-dev libextractor-dev \
- libmicrohttpd-dev libgnutls28-dev
-@end example
-
-Choose one or more database backends@
-SQLite3@
-@code{@
- $ sudo apt-get install libsqlite3-dev@
-}@
-MySQL@
-@code{@
- $ sudo apt-get install libmysqlclient-dev@
-}@
-PostgreSQL@
-@code{@
- $ sudo apt-get install libpq-dev postgresql@
-}
-
-Install the optional dependencies for gnunet-conversation:@
-@code{@
- $ sudo apt-get install gstreamer1.0 libpulse-dev libopus-dev@
-}
-
-Install the libgrypt 1.6:@
-For Ubuntu 14.04:@
-@code{$ sudo apt-get install libgcrypt20-dev}@
-For Ubuntu older 14.04:@
-@code{$ wget ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.6.1.tar.bz2@
- $ tar xf libgcrypt-1.6.1.tar.bz2@
- $ cd libgcrypt-1.6.1@
- $ ./configure@
- $ sudo make install@
- $ cd ..}
-
-Install libgnurl@
-@example
- $ wget https://gnunet.org/sites/default/files/gnurl-7.35.0.tar.bz2@
- $ tar xf gnurl-7.35.0.tar.bz2@
- $ cd gnurl-7.35.0@
- $ ./configure --enable-ipv6 --with-gnutls --without-libssh2 \
- --without-libmetalink --without-winidn --without-librtmp --without-nghttp2 \
- --without-nss --without-cyassl --without-polarssl --without-ssl \
- --without-winssl --without-darwinssl --disable-sspi --disable-ntlm-wb \
- --disable-ldap --disable-rtsp --disable-dict --disable-telnet --disable-tftp \
- --disable-pop3 --disable-imap --disable-smtp --disable-gopher --disable-file \
- --disable-ftp@
- $ sudo make install@
- $ cd ..@
-@end example
-
-Install GNUnet@
-@code{@
- $ wget http://ftpmirror.gnu.org/gnunet/gnunet-0.10.1.tar.gz@
- $ tar xf gnunet-0.10.1.tar.gz@
- $ cd gnunet-0.10.1@
-}
-
-If you want to:
-@itemize @bullet
-
-@item
-Install to a different directory:@
- --prefix=PREFIX
-
-@item
-Have sudo permission, but do not want to compile as root:@
- --with-sudo
-
-@item
-Want debug message enabled:@
- -- enable-logging=verbose
-@end itemize
-
-@code{@
- $ ./configure [ --with-sudo | --prefix=PREFIX | --enable-logging=verbose]@
- $ make; sudo make install@
-}
-
-After installing it, you need to create an empty configuration file:@
-@code{touch ~/.config/gnunet.conf}
-
-And finally you can start GNUnet with@
-@code{$ gnunet-arm -s}
-
-@node Building GLPK for MinGW
-@subsection Building GLPK for MinGW
-
-GNUnet now requires the GNU Linear Programming Kit (GLPK). Since there's is no
-package you can install with @code{mingw-get} you have to compile it from
-source:
-
-@itemize @bullet
-
-@item
-Download the latest version from http://ftp.gnu.org/gnu/glpk/
-
-@item
-Unzip it using your favourite unzipper@
-In the MSYS shell:
-
-@item
-change to the respective directory
-
-@item
-@code{./configure '--build=i686-pc-mingw32'}
-
-@item
-run @code{make install check }
-
-MinGW does not automatically detect the correct buildtype so you have to
-specify it manually
-@end itemize
-
-
-@node GUI build instructions for Ubuntu 12.04 using Subversion
-@subsection GUI build instructions for Ubuntu 12.04 using Subversion
-
-After installing GNUnet you can continue installing the GNUnet GUI tools:
-
-First, install the required dependencies:
-
-@code{@
- $ sudo apt-get install libgladeui-dev libqrencode-dev@
-}
-
-Please ensure that the GNUnet shared libraries can be found by the linker. If
-you installed GNUnet libraries in a non standard path (say
-GNUNET_PREFIX=/usr/local/lib/), you can
-@itemize @bullet
-
-
-@item
-set the environmental variable permanently to@
-@code{LD_LIBRARY_PATH=$GNUNET_PREFIX}
-
-@item
-or add @code{$GNUNET_PREFIX} to @code{/etc/ld.so.conf}
-@end itemize
-
-
-Now you can checkout and compile the GNUnet GUI tools@
-@code{@
- $ svn co https://gnunet.org/svn/gnunet-gtk@
- $ cd gnunet-gtk@
- $ ./bootstrap@
- $ ./configure --prefix=$GNUNET_PREFIX/.. --with-gnunet=$GNUNET_PREFIX/..@
- $ make install@
-}
-
-@node Installation with gnunet-update
-@subsection Installation with gnunet-update
-
-gnunet-update project is an effort to introduce updates to GNUnet
-installations. An interesting to-be-implemented-feature of gnunet-update is
-that these updates are propagated through GNUnet's peer-to-peer network. More
-information about gnunet-update can be found at
-https://gnunet.org/svn/gnunet-update/README.
-
-While the project is still under development, we have implemented the following
-features which we believe may be helpful for users and we would like them to be
-tested:
-
-@itemize @bullet
-
-@item
-Packaging GNUnet installation along with its run-time dependencies into update
-packages
-
-@item
-Installing update packages into compatible hosts
-
-@item
-Updating an existing installation (which had been installed by gnunet-update)
-to a newer one
-@end itemize
-
-The above said features of gnunet-update are currently available for testing on
-GNU/Linux systems.
-
-The following is a guide to help you get started with gnunet-update. It shows
-you how to install the testing binary packages of GNUnet 0.9.1 we have at
-https://gnunet.org/install/
-
-gnunet-update needs the following:
-
-@itemize @bullet
-@item
-python ( 2.6 or above)
-
-@item
-gnupg
-
-@item
-python-gpgme
-@end itemize
-
-
-Checkout gnunet-update:@
-@code{@
- $ svn checkout -r24905 https://gnunet.org/svn/gnunet-update@
-}
-
-For security reasons, all packages released for gnunet-update from us are
-signed with the key at https://gnunet.org/install/key.txt You would need to
-import this key into your gpg key ring. gnunet-update uses this key to verify
-the integrity of the packages it installs@
-@code{@
- $ gpg --recv-keys 7C613D78@
-}
-
-Download the packages relevant to your architecture (currently I have access to
-GNU/Linux machines on x86_64 and i686, so only two for now, hopefully more
-later) from https://gnunet.org/install/.
-
-To install the downloaded package into the directory /foo:
-
-@code{@
- gnunet-update/bin/gnunet-update install downloaded/package /foo@
-}
-
-The installer reports the directories into which shared libraries and
-dependencies have been installed. You may need to add the reported shared
-library installation paths to LD_LIBRARY_PATH before you start running any
-installed binaries.
-
-Please report bugs at https://gnunet.org/bugs/ under the project
-'gnunet-update'.
-
-@node Instructions for Microsoft Windows Platforms (Old)
-@subsection Instructions for Microsoft Windows Platforms (Old)
-
-This document is a DEPRECATED installation guide for gnunet on windows. It will
-not work for recent gnunet versions, but maybe it will be of some use if
-problems arise.
-
- The Windows build uses a UNIX emulator for Windows,
- @uref{http://www.mingw.org/, MinGW}, to build the executable modules. These
- modules run natively on Windows and do not require additional emulation
- software besides the usual dependencies.
-
- GNUnet development is mostly done under Linux and especially SVN checkouts may
- not build out of the box. We regret any inconvenience, and if you have
- problems, please report them.
-
-
-
-@menu
-* Hardware and OS requirements::
-* Software installation::
-* Building libextractor and GNUnet::
-* Installer::
-* Source::
-@end menu
-
-@node Hardware and OS requirements
-@subsubsection Hardware and OS requirements
-
-@itemize @bullet
-
-@item
-Pentium II or equivalent processor, 350 MHz or better
-
-@item
-128 MB RAM
-
-@item
-600 MB free disk space
-
-@item
-Windows 2000 or Windows XP are recommended
-@end itemize
-
-@node Software installation
-@subsubsection Software installation
-
-@itemize @bullet
-
-@item
-@strong{Compression software}@
-@
- The software packages GNUnet depends on are usually compressed using UNIX
- tools like tar, gzip and bzip2.@ If you do not already have an utility that is
- able to extract such archives, get @uref{http://www.7-zip.org/, 7-Zip}.
-
-@item
-@strong{UNIX environment}@
-@
-The MinGW project provides the compiler toolchain that is used to build
-GNUnet.@ Get the following packages from
-@uref{http://sourceforge.net/projects/mingw/files/, the MinGW project}:
-@itemize @bullet
-
-
-@item
-GCC core
-
-@item
-GCC g++
-
-@item
-MSYS
-
-@item
-MSYS Developer Tool Kit (msysDTK)
-
-@item
-MSYS Developer Tool Kit - msys-autoconf (bin)
-
-@item
-MSYS Developer Tool Kit - msys-automake (bin)
-
-@item
-MinGW Runtime
-
-@item
-MinGW Utilities
-
-@item
-Windows API
-
-@item
-Binutils
-
-@item
-make
-
-@item
-pdcurses
-
-@item
-GDB (snapshot)
-@end itemize
-
-@itemize @bullet
-
-
-@item
-Install MSYS (to c:\mingw, for example.)@
-Do @strong{not} use spaces in the pathname (c:\program files\mingw).
-
-@item
-Install MinGW runtime, utilities and GCC to a subdirectory (to c:\mingw\mingw,
-for example)
-
-@item
-Install the Development Kit to the MSYS directory (c:\mingw)
-
-@item
-Create a batch file bash.bat in your MSYS directory with the files:@
-
-@example
-bin\sh.exe --login
-@end example
-
-
-This batch file opens a shell which is used to invoke the build processes..@
-MinGW's standard shell (msys.bat) is not suitable because it opens a separate
-console window@ On Vista, bash.bat needs to be run as administrator.
-
-@item
-Start bash.sh and rename (c:\mingw\mingw\)lib\libstdc++.la to avoid problems:@
-
-@example
-mv /usr/mingw/lib/libstdc++.la /usr/mingw/lib/libstdc++.la.broken
-@end example
-
-
-@item
-Unpack the Windows API to the MinGW directory (c:\mingw\mingw\) and remove the
-declaration of DATADIR from (c:\mingw\mingw\)include\objidl.h (lines 55-58)
-
-@item
-Unpack autoconf, automake to the MSYS directory (c:\mingw)
-
-@item
-Install all other packages to the MinGW directory (c:\mingw\mingw\)
-@end itemize
-
-
-@item
-@strong{GNU Libtool}@
-@
-GNU Libtool is required to use shared libraries.@
-@
-Get the prebuilt package from here and unpack it to the MinGW directory
-(c:\mingw)
-
-@item
-@strong{Pthreads}@
-@
-GNUnet uses the portable POSIX thread library for multi-threading..@
-
-@itemize @bullet
-
-
-@item
-Save @uref{ftp://sources.redhat.com/pub/pthreads-win32/dll-latest/lib/x86
-/libpthreadGC2.a, libpthreadGC2.a} (x86) or @uref{ftp://sources.redhat.c
-om/pub/pthreads-win32/dll-latest/lib/x64/libpthreadGC2.a, libpthreadGC2.
-a} (x64) as libpthread.a into the lib directory (c:\mingw\mingw\lib\libpt
-hread.a)
-
-@item
-Save @uref{ftp://sources.redhat.com/pub/pthreads-win32/dll-latest/lib/x86
-/pthreadGC2.dll, pthreadGC2.dll} (x86) or @uref{ftp://sources.redhat.c
-om/pub/pthreads-win32/dll-latest/lib/x64/pthreadGC2.dll, libpthreadGC2.a}
-(x64) into the MinGW bin directory (c:\mingw\mingw\bin)
-
-@item
-Download all header files from @uref{ftp://sources.redhat.com/pub/pthread
-s-win32/dll-latest/include/, include/} to the @file{include} directory
-(c:\mingw\mingw\include)
-@end itemize
-
-
-@item
-@strong{GNU MP@
-}@
-@
-GNUnet uses the GNU Multiple Precision library for special cryptographic operations.@
-@
-Get the GMP binary package from the
-@uref{http://sourceforge.net/projects/mingwrep/, MinGW repository} and
-unpack it to the MinGW directory (c:\mingw\mingw)
-
-@item
-@strong{GNU Gettext}@
-@
- GNU gettext is used to provide national language support.@
-@
- Get the prebuilt package from hereand unpack it to the MinGW directory (c:\mingw\mingw)
-
-@item
-@strong{GNU iconv}@
-@
- GNU Libiconv is used for character encoding conversion.@
-@
- Get the prebuilt package from here and unpack it to the MinGW directory (c:\mingw\mingw)
-
-@item
-@strong{SQLite}@
-@
- GNUnet uses the SQLite database to store data.@
-@
- Get the prebuilt binary from here and unpack it to your MinGW directory.
-
-@item @strong{MySQL}@
-As an alternative to SQLite, GNUnet also supports MySQL.
-
-@itemize @bullet
-
-@item Get the binary installer from the
-@uref{http://dev.mysql.com/downloads/mysql/4.1.html#Windows, MySQL project}
-(version 4.1), install it and follow the instructions in README.mysql.
-
-@item Create a temporary build directory (c:\mysql)
-
-@item Copy the directories include\ and lib\ from the MySQL directory to
-the new directory
-
-@item Get the patches from
-@uref{http://bugs.mysql.com/bug.php?id=8906&files=1, Bug #8906} and
-@uref{http://bugs.mysql.com/bug.php?id=8872&files=1, Bug #8872} (the
-latter is only required for MySQL
-
-@example
-patch -p 0
-@end example
-
-@item Move lib\opt\libmysql.dll to lib\libmysql.dll
-
-@item Change to lib\ and create an import library:@
-
-@example
-dlltool --input-def ../include/libmySQL.def --dllname libmysql.dll
- --output-lib libmysqlclient.a -k
-@end example
-
-@item Copy include\* to include\mysql\
-
-@item Pass "--with-mysql=/c/mysql" to ./configure and copy libmysql.dll
-to your PATH or GNUnet's @file{bin} directory
-@end itemize
-
-
-@item
-@strong{GTK+}@
-@
- gnunet-gtk and libextractor depend on GTK.@
-@
- Get the the binary and developer packages of atk, glib, gtk, iconv,
- gettext-runtime, pango from
- @uref{ftp://ftp.gtk.org/pub/gtk/v2.6/win32, gtk.org} and unpack it to the
- MinGW directory (c:\mingw\mingw)@
-@
- Get @uref{http://www.gtk.org/download/win32.php, pkg-config} and libpng
- and unpack them to the MinGW directory (c:\mingw\mingw)@
-@
- Here is an all-in-one package for
- @uref{http://ftp.gnome.org/pub/gnome/binaries/win32/gtk+/2.24/gtk+-bundle_2.24.10-20120208_win32.zip, gtk+dependencies}.
- Do not overwrite any existing files!
-
-@item
-@strong{Glade}@
-@
- gnunet-gtk and and gnunet-setup were created using this interface builder
-
-@itemize @bullet
-
-
-@item
- Get the Glade and libglade (-bin and -devel) packages (without GTK!) from
- @uref{http://gladewin32.sourceforge.net/, GladeWin32} and unpack it to
- the MinGW directory (c:\mingw\mingw)
-
-@item
-Get libxml from here and unpack it to the MinGW
-directory (c:\mingw\mingw).
-@end itemize
-
-
-@item
-@strong{zLib}@
-@
-libextractor requires zLib to decompress some file formats. GNUnet uses it
-to (de)compress meta-data.@
-@
- Get zLib from here (Signature) and unpack it to the
- MinGW directory (c:\mingw\mingw)
-
-@item
-@strong{Bzip2}@
-@
- libextractor also requires Bzip2 to decompress some file formats.@
-@
-Get Bzip2 (binary and developer package) from
-@uref{http://gnuwin32.sourceforge.net/packages/bzip2.htm, GnuWin32} and
-unpack it to the MinGW directory (c:\mingw\mingw)
-
-@item
-@strong{Libgcrypt}@
-@
- Libgcrypt provides the cryptographic functions used by GNUnet@
-@
- Get Libgcrypt from @uref{ftp://ftp.gnupg.org/gcrypt/libgcrypt/, here},
- compile and place it in the MinGW directory (c:\mingw\mingw). Currently
- you need at least version 1.4.2 to compile GNUnet.
-
-@item
-@strong{PlibC}@
-@
- PlibC emulates Unix functions under Windows.@
-@
- Get PlibC from here and unpack it to the MinGW
- directory (c:\mingw\mingw)
-
-@item
-@strong{OGG Vorbis}@
-@
- OGG Vorbis is used to extract meta-data from .ogg files@
-@
- Get the packages
- @uref{http://www.gnunet.org/libextractor/download/win/libogg-1.1.4.zip, libogg}
- and
- @uref{http://www.gnunet.org/libextractor/download/win/libvorbis-1.2.3.zip, libvorbis}
- from the
- @uref{http://ftp.gnu.org/gnu/libextractor/libextractor-w32-1.0.0.zip, libextractor win32 build}
- and unpack them to the MinGW directory (c:\mingw\mingw)
-
-@item
-@strong{Exiv2}@
-@
- (lib)Exiv2 is used to extract meta-data from files with Exiv2 meta-data@
-@
- Download
-@uref{http://www.gnunet.org/libextractor/download/win/exiv2-0.18.2.zip, Exiv2}
-and unpack it to the MSYS directory (c:\mingw)
-@end itemize
-
-@node Building libextractor and GNUnet
-@subsubsection Building libextractor and GNUnet
-
-Before you compile libextractor or GNUnet, be sure to set PKG_CONFIG_PATH:
-
-@example
-export PKG_CONFIG_PATH=/mingw/lib/pkgconfig
-@end example
-
-@noindent
-See Installation for basic instructions on building libextractor
-and GNUnet. By default, all modules that are created in this way contain
-debug information and are quite large. To compile release versions (small
-and fast) set the variable CFLAGS:
-
-@example
-export CFLAGS='-O2 -march=pentium -fomit-frame-pointer'
-./configure --prefix=$HOME --with-extractor=$HOME
-@end example
-
-@node Installer
-@subsubsection Installer
-
-The GNUnet installer is made with
-@uref{http://nsis.sourceforge.net/, NSIS}. The installer script is
-located in @file{contrib\win} in the GNUnet source tree.
-
-@node Source
-@subsubsection Source
-
-The sources of all dependencies are available here.
-
-@node Portable GNUnet
-@section Portable GNUnet
-
-Quick instructions on how to use the most recent GNUnet on most GNU/Linux
-distributions
-
-Currently this has only been tested on Ubuntu 12.04, 12.10, 13.04, Debian
-and CentOS 6, but it should work on almost any GNU/Linux distribution.
-More in-detail information can be found in the handbook.
-
-
-
-@menu
-* Prerequisites::
-* Download & set up gnunet-update::
-* Install GNUnet::
-@end menu
-
-@node Prerequisites
-@subsection Prerequisites
-
-Open a terminal and paste this line into it to install all required tools
-needed:@
-@code{sudo apt-get install python-gpgme subversion}
-
-@node Download & set up gnunet-update
-@subsection Download & set up gnunet-update
-
-The following command will download a working version of gnunet-update
-with the subversion tool and import the public key which is needed for
-authentication:
-
-@example
-svn checkout -r24905 https://gnunet.org/svn/gnunet-update ~/gnunet-update
-cd ~/gnunet-update
-gpg --keyserver "hkp://keys.gnupg.net" --recv-keys 7C613D78
-@end example
-
-@node Install GNUnet
-@subsection Install GNUnet
-
-Download and install GNUnet binaries which can be found here and set
-library paths:
-
-@example
-wget -P /tmp https://gnunet.org/install/packs/gnunet-0.9.4-`uname -m`.tgz
-./bin/gnunet-update install /tmp/gnunet-0.9*.tgz ~
-echo "PATH DEFAULT=$@{PATH@}:$HOME/bin" >> ~/.pam_environment
-echo -e "$@{HOME@}/lib\n$@{HOME@}/lib/gnunet-deps" | sudo tee \
- /etc/ld.so.conf.d/gnunet.conf > /dev/null
-sudo ldconfig
-@end example
-
-You may need to re-login once after executing these last commands
-
-That's it, GNUnet is installed in your home directory now. GNUnet can be
-configured and afterwards started by executing @code{gnunet-arm -s}.
-
-@node The graphical configuration interface
-@section The graphical configuration interface
-
-If you also would like to use gnunet-gtk and gnunet-setup (highly
-recommended for beginners), do:
-
-@example
-wget -P /tmp https://gnunet.org/install/packs/gnunet-0.9.4-gtk-0.9.4-`uname -m`.tgz
-sh ~/gnunet-update/bin/gnunet-update install /tmp/gnunet-*gtk*.tgz ~
-sudo ldconfig
-@end example
-
-Now you can run @code{gnunet-setup} for easy configuration of your
-GNUnet peer.
-
-@menu
-* Configuring your peer::
-* Configuring the Friend-to-Friend (F2F) mode::
-* Configuring the hostlist to bootstrap::
-* Configuration of the HOSTLIST proxy settings::
-* Configuring your peer to provide a hostlist ::
-* Configuring the datastore::
-* Configuring the MySQL database::
-* Reasons for using MySQL::
-* Reasons for not using MySQL::
-* Setup Instructions::
-* Testing::
-* Performance Tuning::
-* Setup for running Testcases::
-* Configuring the Postgres database::
-* Reasons to use Postgres::
-* Reasons not to use Postgres::
-* Manual setup instructions::
-* Testing the setup manually::
-* Configuring the datacache::
-* Configuring the file-sharing service::
-* Configuring logging::
-* Configuring the transport service and plugins::
-* Configuring the wlan transport plugin::
-* Configuring HTTP(S) reverse proxy functionality using Apache or nginx::
-* Blacklisting peers::
-* Configuration of the HTTP and HTTPS transport plugins::
-* Configuring the GNU Name System::
-* Configuring the GNUnet VPN::
-* Bandwidth Configuration::
-* Configuring NAT::
-* Peer configuration for distributions::
-@end menu
-
-@node Configuring your peer
-@subsection Configuring your peer
-
-This chapter will describe the various configuration options in GNUnet.
-
-The easiest way to configure your peer is to use the gnunet-setup tool.
-gnunet-setup is part of the gnunet-gtk download. You might have to
-install it separately.
-
-Many of the specific sections from this chapter actually are linked from
-within gnunet-setup to help you while using the setup tool.
-
-While you can also configure your peer by editing the configuration
-file by hand, this is not recommended for anyone except for developers.
-
-
-@node Configuring the Friend-to-Friend (F2F) mode
-@subsection Configuring the Friend-to-Friend (F2F) mode
-
-GNUnet knows three basic modes of operation. In standard "peer-to-peer"
-mode, your peer will connect to any peer. In the pure "friend-to-friend"
-mode, your peer will ONLY connect to peers from a list of friends
-specified in the configuration.
-Finally, in mixed mode, GNUnet will only connect to arbitrary peers if it
-has at least a specified number of connections to friends.
-
-When configuring any of the F2F modes, you first need to create a file
-with the peer identities of your friends. Ask your friends to run
-
-@example
-$ gnunet-peerinfo -sq
-@end example
-
-@noindent
-The output of this command needs to be added to your friends file, which
-is simply a plain text file with one line per friend with the output from
-the above command.
-
-You then specify the location of your friends file in the "FRIENDS"
-option of the "topology" section.
-
-Once you have created the friends file, you can tell GNUnet to only
-connect to your friends by setting the "FRIENDS-ONLY" option (again in
-the "topology" section) to YES.
-
-If you want to run in mixed-mode, set "FRIENDS-ONLY" to NO and configure a
-minimum number of friends to have (before connecting to arbitrary peers)
-under the "MINIMUM-FRIENDS" option.
-
-If you want to operate in normal P2P-only mode, simply set
-"MINIMUM-FRIENDS" to zero and "FRIENDS_ONLY" to NO. This is the default.
-
-@node Configuring the hostlist to bootstrap
-@subsection Configuring the hostlist to bootstrap
-
-After installing the software you need to get connected to the GNUnet
-network. The configuration file included in your download is already
-configured to connect you to the GNUnet network.
-In this section the relevant configuration settings are explained.
-
-To get an initial connection to the GNUnet network and to get to know
-peers already connected to the network you can use the so called
-bootstrap servers.
-These servers can give you a list of peers connected to the network.
-To use these bootstrap servers you have to configure the hostlist daemon
-to activate bootstrapping.
-
-To activate bootstrapping edit your configuration file and edit the
-@code{[hostlist]}-section. You have to set the argument "-b" in the
-options line:
-
-@example
-[hostlist]
-OPTIONS = -b
-@end example
-
-Additionally you have to specify which server you want to use.
-The default bootstrapping server is
-"@uref{http://v10.gnunet.org/hostlist, http://v10.gnunet.org/hostlist}".
-[^] To set the server you have to edit the line "SERVERS" in the hostlist
-section. To use the default server you should set the lines to
-
-@example
-SERVERS = http://v10.gnunet.org/hostlist [^]
-@end example
-
-@noindent
-To use bootstrapping your configuration file should include these lines:
-
-@example
-[hostlist]
-OPTIONS = -b
-SERVERS = http://v10.gnunet.org/hostlist [^]
-@end example
-
-@noindent
-Besides using bootstrap servers you can configure your GNUnet peer to
-recieve hostlist advertisements.
-Peers offering hostlists to other peers can send advertisement messages
-to peers that connect to them. If you configure your peer to receive these
-messages, your peer can download these lists and connect to the peers
-included. These lists are persistent, which means that they are saved to
-your hard disk regularly and are loaded during startup.
-
-To activate hostlist learning you have to add the "-e" switch to the
-OPTIONS line in the hostlist section:
-
-@example
-[hostlist]
-OPTIONS = -b -e
-@end example
-
-@noindent
-Furthermore you can specify in which file the lists are saved. To save the
-lists in the file "hostlists.file" just add the line:
-
-@example
-HOSTLISTFILE = hostlists.file
-@end example
-
-@noindent
-Best practice is to activate both bootstrapping and hostlist learning.
-So your configuration file should include these lines:
-
-@example
-[hostlist]
-OPTIONS = -b -e
-HTTPPORT = 8080
-SERVERS = http://v10.gnunet.org/hostlist [^]
-HOSTLISTFILE = $SERVICEHOME/hostlists.file
-@end example
-
-@node Configuration of the HOSTLIST proxy settings
-@subsection Configuration of the HOSTLIST proxy settings
-
-The hostlist client can be configured to use a proxy to connect to the
-hostlist server.
-This functionality can be configured in the configuration file directly
-or using the gnunet-setup tool.
-
-The hostlist client supports the following proxy types at the moment:
-
-@itemize @bullet
-@item HTTP and HTTP 1.0 only proxy
-@item SOCKS 4/4a/5/5 with hostname
-@end itemize
-
-In addition authentication at the proxy with username and password can be
-configured.
-
-To configure proxy support for the hostlist client in the gnunet-setup
-tool, select the "hostlist" tab and select the appropriate proxy type.
-The hostname or IP address (including port if required) has to be entered
-in the "Proxy hostname" textbox. If required, enter username and password
-in the "Proxy username" and "Proxy password" boxes.
-Be aware that these information will be stored in the configuration in
-plain text.
-
-To configure these options directly in the configuration, you can
-configure the following settings in the
-@code{[hostlist]} section of the configuration:
-
-@example
- # Type of proxy server,@
- # Valid values: HTTP, HTTP_1_0, SOCKS4, SOCKS5, SOCKS4A, SOCKS5_HOSTNAME@
- # Default: HTTP@
- # PROXY_TYPE = HTTP
-
-# Hostname or IP of proxy server@
- # PROXY =@
- # User name for proxy server@
- # PROXY_USERNAME =@
- # User password for proxy server@
- # PROXY_PASSWORD =@
-@end example
-
-@node Configuring your peer to provide a hostlist
-@subsection Configuring your peer to provide a hostlist
-
-If you operate a peer permanently connected to GNUnet you can configure
-your peer to act as a hostlist server, providing other peers the list of
-peers known to him.
-
-Yor server can act as a bootstrap server and peers needing to obtain a
-list of peers can contact him to download this list.
-To download this hostlist the peer uses HTTP.
-For this reason you have to build your peer with libcurl and microhttpd
-support. How you build your peer with this options can be found here:
-@uref{https://gnunet.org/generic_installation}
-
-To configure your peer to act as a bootstrap server you have to add the
-"@code{-p}" option to OPTIONS in the @code{[hostlist]} section of your
-configuration file. Besides that you have to specify a port number for
-the http server. In conclusion you have to add the following lines:
-
-@example
-[hostlist]
-HTTPPORT = 12980
-OPTIONS = -p
-@end example
-
-@noindent
-If your peer acts as a bootstrap server other peers should know about
-that. You can advertise the hostlist your are providing to other peers.
-Peers connecting to your peer will get a message containing an
-advertisement for your hostlist and the URL where it can be downloaded.
-If this peer is in learning mode, it will test the hostlist and, in the
-case it can obtain the list successfully, it will save it for
-bootstrapping.
-
-To activate hostlist advertisement on your peer, you have to set the
-following lines in your configuration file:
-
-@example
-[hostlist]
-EXTERNAL_DNS_NAME = example.org
-HTTPPORT = 12981
-OPTIONS = -p -a
-@end example
-
-@noindent
-With this configuration your peer will a act as a bootstrap server and
-advertise this hostlist to other peers connecting to him. The URL used to
-download the list will be
-@code{@uref{http://example.org:12981/, http://example.org:12981/}}.
-
-Please notice:
-@itemize @bullet
-@item The hostlist is not human readable, so you should not try to
-download it using your webbrowser. Just point your GNUnet peer to the
-address!
-@item Advertising without providing a hostlist does not make sense and
-will not work.
-@end itemize
-
-@node Configuring the datastore
-@subsection Configuring the datastore
-
-The datastore is what GNUnet uses to for long-term storage of file-sharing
-data. Note that long-term does not mean 'forever' since content does have
-an expiration date, and of course storage space is finite (and hence
-sometimes content may have to be discarded).
-
-Use the "QUOTA" option to specify how many bytes of storage space you are
-willing to dedicate to GNUnet.
-
-In addition to specifying the maximum space GNUnet is allowed to use for
-the datastore, you need to specify which database GNUnet should use to do
-so. Currently, you have the choice between sqLite, MySQL and Postgres.
-
-@node Configuring the MySQL database
-@subsection Configuring the MySQL database
-
-This section describes how to setup the MySQL database for GNUnet.
-
-Note that the mysql plugin does NOT work with mysql before 4.1 since we
-need prepared statements.
-We are generally testing the code against MySQL 5.1 at this point.
-
-@node Reasons for using MySQL
-@subsection Reasons for using MySQL
-
-@itemize @bullet
-
-@item
-On up-to-date hardware where mysql can be used comfortably, this module
-will have better performance than the other database choices (according
-to our tests).
-
-@item Its often possible to recover the mysql database from internal
-inconsistencies. Some of the other databases do not support repair.
-@end itemize
-
-@node Reasons for not using MySQL
-@subsection Reasons for not using MySQL
-
-@itemize @bullet
-@item Memory usage (likely not an issue if you have more than 1 GB)
-@item Complex manual setup
-@end itemize
-
-@node Setup Instructions
-@subsection Setup Instructions
-
-@itemize @bullet
-@item In @code{gnunet.conf} set in section "DATASTORE" the value for
-"DATABASE" to "mysql".
-@item Access mysql as root:@
-
-@example
-$ mysql -u root -p
-@end example
-
-@noindent
-and issue the following commands, replacing $USER with the username
-that will be running gnunet-arm (so typically "gnunet"):
-
-@example
-CREATE DATABASE gnunet;
-GRANT select,insert,update,delete,create,alter,drop,create temporary tables
- ON gnunet.* TO $USER@@localhost;
-SET PASSWORD FOR $USER@@localhost=PASSWORD('$the_password_you_like');
-FLUSH PRIVILEGES;
-@end example
-
-@item
-In the $HOME directory of $USER, create a ".my.cnf" file with the
-following lines
-
-@example
-[client]
-user=$USER
-password=$the_password_you_like
-@end example
-
-@end itemize
-
-Thats it. Note that @code{.my.cnf} file is a slight security risk unless
-its on a safe partition. The $HOME/.my.cnf can of course be a symbolic
-link. Luckily $USER has only priviledges to mess up GNUnet's tables,
-which should be pretty harmless.
-
-@node Testing
-@subsection Testing
-
-You should briefly try if the database connection works. First, login
-as $USER. Then use:
-
-@example
-$ mysql -u $USER
-mysql> use gnunet;
-@end example
-
-@noindent
-If you get the message "Database changed" it probably works.
-
-If you get "ERROR 2002: Can't connect to local MySQL server@
-through socket '/tmp/mysql.sock' (2)" it may be resolvable by@
-"ln -s /var/run/mysqld/mysqld.sock /tmp/mysql.sock"@
-so there may be some additional trouble depending on your mysql setup.
-
-@node Performance Tuning
-@subsection Performance Tuning
-
-For GNUnet, you probably want to set the option
-
-@example
-innodb_flush_log_at_trx_commit = 0
-@end example
-
-@noindent
-for a rather dramatic boost in MySQL performance. However, this reduces
-the "safety" of your database as with this options you may loose
-transactions during a power outage.
-While this is totally harmless for GNUnet, the option applies to all
-applications using MySQL. So you should set it if (and only if) GNUnet is
-the only application on your system using MySQL.
-
-@node Setup for running Testcases
-@subsection Setup for running Testcases
-
-If you want to run the testcases, you must create a second database
-"gnunetcheck" with the same username and password. This database will
-then be used for testing ("make check").
-
-@node Configuring the Postgres database
-@subsection Configuring the Postgres database
-
-This text describes how to setup the Postgres database for GNUnet.
-
-This Postgres plugin was developed for Postgres 8.3 but might work for
-earlier versions as well.
-
-@node Reasons to use Postgres
-@subsection Reasons to use Postgres
-
-@itemize @bullet
-@item Easier to setup than MySQL
-@item Real database
-@end itemize
-
-@node Reasons not to use Postgres
-@subsection Reasons not to use Postgres
-
-@itemize @bullet
-@item Quite slow
-@item Still some manual setup required
-@end itemize
-
-@node Manual setup instructions
-@subsection Manual setup instructions
-
-@itemize @bullet
-@item In @code{gnunet.conf} set in section "DATASTORE" the value for
-"DATABASE" to "postgres".
-@item Access Postgres to create a user:@
-
-@table @asis
-@item with Postgres 8.x, use:
-
-@example
-# su - postgres
-$ createuser
-@end example
-
-@noindent
-and enter the name of the user running GNUnet for the role interactively.
-Then, when prompted, do not set it to superuser, allow the creation of
-databases, and do not allow the creation of new roles.@
-
-@item with Postgres 9.x, use:
-
-@example
-# su - postgres
-$ createuser -d $GNUNET_USER
-@end example
-
-@noindent
-where $GNUNET_USER is the name of the user running GNUnet.@
-
-@end table
-
-
-@item
-As that user (so typically as user "gnunet"), create a database (or two):@
-
-@example
-$ createdb gnunet
-# this way you can run "make check"
-$ createdb gnunetcheck
-@end example
-
-@end itemize
-
-Now you should be able to start @code{gnunet-arm}.
-
-@node Testing the setup manually
-@subsection Testing the setup manually
-
-You may want to try if the database connection works. First, again login
-as the user who will run gnunet-arm. Then use,
-
-@example
-$ psql gnunet # or gnunetcheck
-gnunet=> \dt
-@end example
-
-@noindent
-If, after you have started gnunet-arm at least once, you get
-a @code{gn090} table here, it probably works.
-
-@node Configuring the datacache
-@subsection Configuring the datacache
-@c %**end of header
-
-The datacache is what GNUnet uses for storing temporary data. This data is
-expected to be wiped completely each time GNUnet is restarted (or the
-system is rebooted).
-
-You need to specify how many bytes GNUnet is allowed to use for the
-datacache using the "QUOTA" option in the section "dhtcache".
-Furthermore, you need to specify which database backend should be used to
-store the data. Currently, you have the choice between
-sqLite, MySQL and Postgres.
-
-@node Configuring the file-sharing service
-@subsection Configuring the file-sharing service
-
-In order to use GNUnet for file-sharing, you first need to make sure
-that the file-sharing service is loaded.
-This is done by setting the AUTOSTART option in section "fs" to "YES".
-Alternatively, you can run
-
-@example
-$ gnunet-arm -i fs
-@end example
-
-@noindent
-to start the file-sharing service by hand.
-
-Except for configuring the database and the datacache the only important
-option for file-sharing is content migration.
-
-Content migration allows your peer to cache content from other peers as
-well as send out content stored on your system without explicit requests.
-This content replication has positive and negative impacts on both system
-performance and privacy.
-
-FIXME: discuss the trade-offs. Here is some older text about it...
-
-Setting this option to YES allows gnunetd to migrate data to the local
-machine. Setting this option to YES is highly recommended for efficiency.
-Its also the default. If you set this value to YES, GNUnet will store
-content on your machine that you cannot decrypt.
-While this may protect you from liability if the judge is sane, it may
-not (IANAL). If you put illegal content on your machine yourself, setting
-this option to YES will probably increase your chances to get away with it
-since you can plausibly deny that you inserted the content.
-Note that in either case, your anonymity would have to be broken first
-(which may be possible depending on the size of the GNUnet network and the
-strength of the adversary).
-
-@node Configuring logging
-@subsection Configuring logging
-
-Logging in GNUnet 0.9.0 is controlled via the "-L" and "-l" options.
-Using "-L", a log level can be specified. With log level "ERROR" only
-serious errors are logged.
-The default log level is "WARNING" which causes anything of
-concern to be logged. Log level "INFO" can be used to log anything that
-might be interesting information whereas "DEBUG" can be used by
-developers to log debugging messages (but you need to run configure with
-@code{--enable-logging=verbose} to get them compiled).
-The "-l" option is used to specify the log file.
-
-Since most GNUnet services are managed by @code{gnunet-arm}, using the
-"-l" or "-L" options directly is not possible.
-Instead, they can be specified using the "OPTIONS" configuration value in
-the respective section for the respective service.
-In order to enable logging globally without editing the "OPTIONS" values
-for each service, @code{gnunet-arm} supports a "GLOBAL_POSTFIX" option.
-The value specified here is given as an extra option to all services for
-which the configuration does contain a service-specific "OPTIONS" field.
-
-"GLOBAL_POSTFIX" can contain the special sequence "@{@}" which is replaced
-by the name of the service that is being started. Furthermore,
-@code{GLOBAL_POSTFIX} is special in that sequences starting with "$"
-anywhere in the string are expanded (according to options in "PATHS");
-this expansion otherwise is only happening for filenames and then the "$"
-must be the first character in the option. Both of these restrictions do
-not apply to "GLOBAL_POSTFIX".
-Note that specifying @code{%} anywhere in the "GLOBAL_POSTFIX" disables
-both of these features.
-
-In summary, in order to get all services to log at level "INFO" to
-log-files called @code{SERVICENAME-logs}, the following global prefix
-should be used:
-
-@example
-GLOBAL_POSTFIX = -l $SERVICEHOME/@{@}-logs -L INFO
-@end example
-
-@node Configuring the transport service and plugins
-@subsection Configuring the transport service and plugins
-
-The transport service in GNUnet is responsible to maintain basic
-connectivity to other peers.
-Besides initiating and keeping connections alive it is also responsible
-for address validation.
-
-The GNUnet transport supports more than one transport protocol.
-These protocols are configured together with the transport service.
-
-The configuration section for the transport service itself is quite
-similar to all the other services
-
-@example
- AUTOSTART = YES@
- @@UNIXONLY@@ PORT = 2091@
- HOSTNAME = localhost@
- HOME = $SERVICEHOME@
- CONFIG = $DEFAULTCONFIG@
- BINARY = gnunet-service-transport@
- #PREFIX = valgrind@
- NEIGHBOUR_LIMIT = 50@
- ACCEPT_FROM = 127.0.0.1;@
- ACCEPT_FROM6 = ::1;@
- PLUGINS = tcp udp@
- UNIXPATH = /tmp/gnunet-service-transport.sock@
-@end example
-
-Different are the settings for the plugins to load @code{PLUGINS}.
-The first setting specifies which transport plugins to load.
-
-@itemize @bullet
-@item transport-unix
-A plugin for local only communication with UNIX domain sockets. Used for
-testing and available on unix systems only. Just set the port
-
-@example
- [transport-unix]@
- PORT = 22086@
- TESTING_IGNORE_KEYS = ACCEPT_FROM;@
-@end example
-
-@item transport-tcp
-A plugin for communication with TCP. Set port to 0 for client mode with
-outbound only connections
-
-@example
- [transport-tcp]@
- # Use 0 to ONLY advertise as a peer behind NAT (no port binding)@
- PORT = 2086@
- ADVERTISED_PORT = 2086@
- TESTING_IGNORE_KEYS = ACCEPT_FROM;@
- # Maximum number of open TCP connections allowed@
- MAX_CONNECTIONS = 128@
-@end example
-
-@item transport-udp
-A plugin for communication with UDP. Supports peer discovery using
-broadcasts.
-
-@example
- [transport-udp]@
- PORT = 2086@
- BROADCAST = YES@
- BROADCAST_INTERVAL = 30 s@
- MAX_BPS = 1000000@
- TESTING_IGNORE_KEYS = ACCEPT_FROM;@
-@end example
-
-@item transport-http
-HTTP and HTTPS support is split in two part: a client plugin initiating
-outbound connections and a server part accepting connections from the
-client. The client plugin just takes the maximum number of connections as
-an argument.
-
-@example
- [transport-http_client]@
- MAX_CONNECTIONS = 128@
- TESTING_IGNORE_KEYS = ACCEPT_FROM;@
-@end example
-
-@example
- [transport-https_client]@
- MAX_CONNECTIONS = 128@
- TESTING_IGNORE_KEYS = ACCEPT_FROM;@
-@end example
-
-@noindent
-The server has a port configured and the maximum nunber of connections.
-The HTTPS part has two files with the certificate key and the certificate
-file.
-
-The server plugin supports reverse proxies, so a external hostname can be
-set using the @code{EXTERNAL_HOSTNAME} setting.
-The webserver under this address should forward the request to the peer
-and the configure port.
-
-@example
- [transport-http_server]@
- EXTERNAL_HOSTNAME = fulcrum.net.in.tum.de/gnunet@
- PORT = 1080@
- MAX_CONNECTIONS = 128@
- TESTING_IGNORE_KEYS = ACCEPT_FROM;@
-@end example
-
-@example
- [transport-https_server]@
- PORT = 4433@
- CRYPTO_INIT = NORMAL@
- KEY_FILE = https.key@
- CERT_FILE = https.cert@
- MAX_CONNECTIONS = 128@
- TESTING_IGNORE_KEYS = ACCEPT_FROM;@
-@end example
-
-@item transport-wlan
-
-There is a special article how to setup the WLAN plugin, so here only the
-settings. Just specify the interface to use:
-
-@example
- [transport-wlan]@
- # Name of the interface in monitor mode (typically monX)@
- INTERFACE = mon0@
- # Real hardware, no testing@
- TESTMODE = 0@
- TESTING_IGNORE_KEYS = ACCEPT_FROM;@
-@end example
-@end itemize
-
-@node Configuring the wlan transport plugin
-@subsection Configuring the wlan transport plugin
-
-
-The wlan transport plugin enables GNUnet to send and to receive data on a
-wlan interface.
-It has not to be connected to a wlan network as long as sender and
-receiver are on the same channel. This enables you to get connection to
-the GNUnet where no internet access is possible, for example while
-catastrophes or when censorship cuts you off the internet.
-
-
-@menu
-* Requirements for the WLAN plugin::
-* Configuration::
-* Before starting GNUnet::
-* Limitations and known bugs::
-@end menu
-
-
-@node Requirements for the WLAN plugin
-@subsubsection Requirements for the WLAN plugin
-
-@itemize @bullet
-
-@item wlan network card with monitor support and packet injection
-(see @uref{http://www.aircrack-ng.org/, aircrack-ng.org})
-
-@item Linux kernel with mac80211 stack, introduced in 2.6.22, tested with
-2.6.35 and 2.6.38
-
-@item Wlantools to create the a monitor interface, tested with airmon-ng
-of the aircrack-ng package
-@end itemize
-
-@node Configuration
-@subsubsection Configuration
-
-There are the following options for the wlan plugin (they should be like
-this in your default config file, you only need to adjust them if the
-values are incorrect for your system)
-
-@example
-# section for the wlan transport plugin@
-[transport-wlan]@
-# interface to use, more information in the
-# "Before starting GNUnet" section of the handbook.
-INTERFACE = mon0@
-# testmode for developers:@
-# 0 use wlan interface,@
-#1 or 2 use loopback driver for tests 1 = server, 2 = client@
-TESTMODE = 0@
-@end example
-
-@node Before starting GNUnet
-@subsubsection Before starting GNUnet
-
-Before starting GNUnet, you have to make sure that your wlan interface is
-in monitor mode. One way to put the wlan interface into monitor mode (if
-your interface name is wlan0) is by executing:
-
-@example
- sudo airmon-ng start wlan0@
-@end example
-
-@noindent
-Here is an example what the result should look like:
-
-@example
- Interface Chipset Driver@
- wlan0 Intel 4965 a/b/g/n iwl4965 - [phy0]@
- (monitor mode enabled on mon0)@
-@end example
-
-@noindent
-The monitor interface is mon0 is the one that you have to put into the
-configuration file.
-
-@node Limitations and known bugs
-@subsubsection Limitations and known bugs
-
-Wlan speed is at the maximum of 1 Mbit/s because support for choosing the
-wlan speed with packet injection was removed in newer kernels.
-Please pester the kernel developers about fixing this.
-
-The interface channel depends on the wlan network that the card is
-connected to. If no connection has been made since the start of the
-computer, it is usually the first channel of the card.
-Peers will only find each other and communicate if they are on the same
-channel. Channels must be set manually (i.e. using
-@code{iwconfig wlan0 channel 1}).
-
-
-@node Configuring HTTP(S) reverse proxy functionality using Apache or nginx
-@subsection Configuring HTTP(S) reverse proxy functionality using Apache or nginx
-
-The HTTP plugin supports data transfer using reverse proxies. A reverse
-proxy forwards the HTTP request he receives with a certain URL to another
-webserver, here a GNUnet peer.
-
-So if you have a running Apache or nginx webserver you can configure it to
-be a GNUnet reverse proxy. Especially if you have a well-known webiste
-this improves censorship resistance since it looks as normal surfing
-behaviour.
-
-To do so, you have to do two things:
-
-@itemize @bullet
-@item Configure your webserver to forward the GNUnet HTTP traffic
-@item Configure your GNUnet peer to announce the respective address
-@end itemize
-
-As an example we want to use GNUnet peer running:
-
-@itemize @bullet
-
-@item HTTP server plugin on @code{gnunet.foo.org:1080}
-
-@item HTTPS server plugin on @code{gnunet.foo.org:4433}
-
-@item A apache or nginx webserver on
-@uref{http://www.foo.org/, http://www.foo.org:80/}
-
-@item A apache or nginx webserver on https://www.foo.org:443/
-@end itemize
-
-And we want the webserver to accept GNUnet traffic under
-@code{http://www.foo.org/bar/}. The required steps are described here:
-
-@strong{Configure your Apache2 HTTP webserver}
-
-First of all you need mod_proxy installed.
-
-Edit your webserver configuration. Edit
-@code{/etc/apache2/apache2.conf} or the site-specific configuration file.
-
-In the respective @code{server config},@code{virtual host} or
-@code{directory} section add the following lines:
-
-@example
- ProxyTimeout 300@
- ProxyRequests Off@
- <Location /bar/ >@
- ProxyPass http://gnunet.foo.org:1080/@
- ProxyPassReverse http://gnunet.foo.org:1080/@
- </Location>@
-@end example
-
-@noindent
-@strong{Configure your Apache2 HTTPS webserver}
-
-We assume that you already have an HTTPS server running, if not please
-check how to configure a HTTPS host. An easy to use example is the
-@file{apache2/sites-available/default-ssl} example configuration file.
-
-In the respective HTTPS @code{server config},@code{virtual host} or
-@code{directory} section add the following lines:
-
-@example
- SSLProxyEngine On@
- ProxyTimeout 300@
- ProxyRequests Off@
- <Location /bar/ >@
- ProxyPass https://gnunet.foo.org:4433/@
- ProxyPassReverse https://gnunet.foo.org:4433/@
- </Location>@
-@end example
-
-@noindent
-More information about the apache mod_proxy configuration can be found
-at @uref{http://httpd.apache.org/docs/2.2/mod/mod_proxy.html#proxypass, http://httpd.apache.org/docs/2.2/mod/mod_proxy.html#proxypass}
-
-@strong{Configure your nginx HTTPS webserver}
-
-Since nginx does not support chunked encoding, you first of all have to
-install @code{chunkin}:@
-@uref{http://wiki.nginx.org/HttpChunkinModule, http://wiki.nginx.org/HttpChunkinModule}
-
-To enable chunkin add:
-
-@example
- chunkin on;@
- error_page 411 = @@my_411_error;@
- location @@my_411_error @{@
- chunkin_resume;@
- @}@
-@end example
-
-@noindent
-Edit your webserver configuration. Edit @file{/etc/nginx/nginx.conf} or
-the site-specific configuration file.
-
-In the @code{server} section add:@
-
-@example
- location /bar/@
- @{@
- proxy_pass http://gnunet.foo.org:1080/;@
- proxy_buffering off;@
- proxy_connect_timeout 5; # more than http_server@
- proxy_read_timeout 350; # 60 default, 300s is GNUnet's idle timeout@
- proxy_http_version 1.1; # 1.0 default@
- proxy_next_upstream error timeout invalid_header http_500 http_503 http_502 http_504;@
- @}@
-@end example
-
-@noindent
-@strong{Configure your nginx HTTPS webserver}
-
-Edit your webserver configuration. Edit @file{/etc/nginx/nginx.conf} or
-the site-specific configuration file.
-
-In the @code{server} section add:
-
-@example
- ssl_session_timeout 6m;@
- location /bar/@
- @{@
- proxy_pass https://gnunet.foo.org:4433/;@
- proxy_buffering off;@
- proxy_connect_timeout 5; # more than http_server@
- proxy_read_timeout 350; # 60 default, 300s is GNUnet's idle timeout@
- proxy_http_version 1.1; # 1.0 default@
- proxy_next_upstream error timeout invalid_header http_500 http_503 http_502 http_504;@
- @}@
-@end example
-
-@noindent
-@strong{Configure your GNUnet peer}
-
-To have your GNUnet peer announce the address, you have to specify the
-@code{EXTERNAL_HOSTNAME} option in the @code{[transport-http_server]}
-section:
-
-@example
- [transport-http_server]@
- EXTERNAL_HOSTNAME = http://www.foo.org/bar/@
-@end example
-
-@noindent
-and/or @code{[transport-https_server]} section:
-
-@example
- [transport-https_server]@
- EXTERNAL_HOSTNAME = https://www.foo.org/bar/@
-@end example
-
-@noindent
-Now restart your webserver and your peer...
-
-@node Blacklisting peers
-@subsection Blacklisting peers
-
-Transport service supports to deny connecting to a specific peer of to a
-specific peer with a specific transport plugin using te blacklisting
-component of transport service. With@ blacklisting it is possible to deny
-connections to specific peers of@ to use a specific plugin to a specific
-peer. Peers can be blacklisted using@ the configuration or a blacklist
-client can be asked.
-
-To blacklist peers using the configuration you have to add a section to
-your@ configuration containing the peer id of the peer to blacklist and
-the plugin@ if required.
-
-Example:@
-
-To blacklist connections to P565... on peer AG2P... using tcp add:@
-
-@c FIXME: This is too long and produces errors in the pdf.
-@example
- [transport-blacklist AG2PHES1BARB9IJCPAMJTFPVJ5V3A72S3F2A8SBUB8DAQ2V0O3V8G6G2JU56FHGFOHMQVKBSQFV98TCGTC3RJ1NINP82G0RC00N1520]@
- P565723JO1C2HSN6J29TAQ22MN6CI8HTMUU55T0FUQG4CMDGGEQ8UCNBKUMB94GC8R9G4FB2SF9LDOBAJ6AMINBP4JHHDD6L7VD801G = tcp@
-@end example
-
-To blacklist connections to P565... on peer AG2P... using all plugins add:@
-
-@example
- [transport-blacklist-AG2PHES1BARB9IJCPAMJTFPVJ5V3A72S3F2A8SBUB8DAQ2V0O3V8G6G2JU56FHGFOHMQVKBSQFV98TCGTC3RJ1NINP82G0RC00N1520]@
- P565723JO1C2HSN6J29TAQ22MN6CI8HTMUU55T0FUQG4CMDGGEQ8UCNBKUMB94GC8R9G4FB2SF9LDOBAJ6AMINBP4JHHDD6L7VD801G =@
-@end example
-
-You can also add a blacklist client usign the blacklist api. On a
-blacklist check, blacklisting first checks internally if the peer is
-blacklisted and if not, it asks the blacklisting clients. Clients are
-asked if it is OK to connect to a peer ID, the plugin is omitted.
-
-On blacklist check for (peer, plugin)
-@itemize @bullet
-@item Do we have a local blacklist entry for this peer and this plugin?@
-@item YES: disallow connection@
-@item Do we have a local blacklist entry for this peer and all plugins?@
-@item YES: disallow connection@
-@item Does one of the clients disallow?@
-@item YES: disallow connection
-@end itemize
-
-@node Configuration of the HTTP and HTTPS transport plugins
-@subsection Configuration of the HTTP and HTTPS transport plugins
-
-The client part of the http and https transport plugins can be configured
-to use a proxy to connect to the hostlist server. This functionality can
-be configured in the configuration file directly or using the
-gnunet-setup tool.
-
-The both the HTTP and HTTPS clients support the following proxy types at
-the moment:
-
-@itemize @bullet
-@item HTTP 1.1 proxy
-@item SOCKS 4/4a/5/5 with hostname
-@end itemize
-
-In addition authentication at the proxy with username and password can be
-configured.
-
-To configure proxy support for the clients in the gnunet-setup tool,
-select the "transport" tab and activate the respective plugin. Now you
-can select the appropriate proxy type. The hostname or IP address
-(including port if required) has to be entered in the "Proxy hostname"
-textbox. If required, enter username and password in the "Proxy username"
-and "Proxy password" boxes. Be aware that these information will be stored
-in the configuration in plain text.
-
-To configure these options directly in the configuration, you can
-configure the following settings in the [transport-http_client] and
-[transport-https_client] section of the configuration:
-
-@example
-# Type of proxy server,@
-# Valid values: HTTP, SOCKS4, SOCKS5, SOCKS4A, SOCKS5_HOSTNAME@
-# Default: HTTP@
-# PROXY_TYPE = HTTP
-
-# Hostname or IP of proxy server@
-# PROXY =@
-# User name for proxy server@
-# PROXY_USERNAME =@
-# User password for proxy server@
-# PROXY_PASSWORD =
-@end example
-
-@node Configuring the GNU Name System
-@subsection Configuring the GNU Name System
-
-@menu
-* Configuring system-wide DNS interception::
-* Configuring the GNS nsswitch plugin::
-* Configuring GNS on W32::
-* GNS Proxy Setup::
-* Setup of the GNS CA::
-* Testing the GNS setup::
-* Automatic Shortening in the GNU Name System::
-@end menu
-
-
-@node Configuring system-wide DNS interception
-@subsubsection Configuring system-wide DNS interception
-
-Before you install GNUnet, make sure you have a user and group 'gnunet'
-as well as an empty group 'gnunetdns'.
-
-When using GNUnet with system-wide DNS interception, it is absolutely
-necessary for all GNUnet service processes to be started by
-@code{gnunet-service-arm} as user and group 'gnunet'. You also need to be
-sure to run @code{make install} as root (or use the @code{sudo} option to
-configure) to grant GNUnet sufficient privileges.
-
-With this setup, all that is required for enabling system-wide DNS
-interception is for some GNUnet component (VPN or GNS) to request it.
-The @code{gnunet-service-dns} will then start helper programs that will
-make the necessary changes to your firewall (@code{iptables}) rules.
-
-Note that this will NOT work if your system sends out DNS traffic to a
-link-local IPv6 address, as in this case GNUnet can intercept the traffic,
-but not inject the responses from the link-local IPv6 address. Hence you
-cannot use system-wide DNS interception in conjunction with link-local
-IPv6-based DNS servers. If such a DNS server is used, it will bypass
-GNUnet's DNS traffic interception.
-
-Using the GNU Name System (GNS) requires two different configuration
-steps.
-First of all, GNS needs to be integrated with the operating system. Most
-of this section is about the operating system level integration.
-
-Additionally, each individual user who wants to use the system must also
-initialize his GNS zones. This can be done by running (after starting
-GNUnet)
-
-@example
-$ gnunet-gns-import.sh
-@end example
-
-@noindent
-after the local GNUnet peer has been started. Note that the namestore (in
-particular the namestore database backend) should not be reconfigured
-afterwards (as records are not automatically migrated between backends).
-
-The remainder of this chapter will detail the various methods for
-configuring the use of GNS with your operating system.
-
-At this point in time you have different options depending on your OS:
-
-@table @asis
-
-@item Use the gnunet-gns-proxy This approach works for all operating
-systems and is likely the easiest. However, it enables GNS only for
-browsers, not for other applications that might be using DNS, such as SSH.
-Still, using the proxy is required for using HTTP with GNS and is thus
-recommended for all users. To do this, you simply have to run the
-@code{gnunet-gns-proxy-setup-ca} script as the user who will run the
-browser (this will create a GNS certificate authority (CA) on your system
-and import its key into your browser), then start @code{gnunet-gns-proxy}
-and inform your browser to use the Socks5 proxy which
-@code{gnunet-gns-proxy} makes available by default on port 7777.
-@item Use a nsswitch plugin (recommended on GNU systems)
-This approach has the advantage of offering fully personalized resolution
-even on multi-user systems. A potential disadvantage is that some
-applications might be able to bypass GNS.
-@item Use a W32 resolver plugin (recommended on W32)
-This is currently the only option on W32 systems.
-@item Use system-wide DNS packet interception
-This approach is recommended for the GNUnet VPN. It can be used to handle
-GNS at the same time; however, if you only use this method, you will only
-get one root zone per machine (not so great for multi-user systems).
-@end table
-
-You can combine system-wide DNS packet interception with the nsswitch
-plugin.
-The setup of the system-wide DNS interception is described here. All of
-the other GNS-specific configuration steps are described in the following
-sections.
-
-@node Configuring the GNS nsswitch plugin
-@subsubsection Configuring the GNS nsswitch plugin
-
-The Name Service Switch (NSS) is a facility in Unix-like operating systems
-that provides a variety of sources for common configuration databases and
-name resolution mechanisms.
-A system administrator usually configures the operating system's name
-services using the file @file{/etc/nsswitch.conf}.
-
-GNS provides a NSS plugin to integrate GNS name resolution with the
-operating system's name resolution process.
-To use the GNS NSS plugin you have to either
-
-@itemize @bullet
-@item install GNUnet as root or
-@item compile GNUnet with the @code{--with-sudo=yes} switch.
-@end itemize
-
-Name resolution is controlled by the @emph{hosts} section in the NSS
-configuration. By default this section first performs a lookup in the
-/etc/hosts file and then in DNS. The nsswitch file should contain a line
-similar to:
-
-@example
-hosts: files dns [NOTFOUND=return] mdns4_minimal mdns4
-@end example
-
-@noindent
-Here the GNS NSS plugin can be added to perform a GNS lookup before
-performing a DNS lookup.
-The GNS NSS plugin has to be added to the "hosts" section in
-@file{/etc/nsswitch.conf} file before DNS related plugins:
-
-@example
-...
-hosts: files gns [NOTFOUND=return] dns mdns4_minimal mdns4
-...
-@end example
-
-@noindent
-The @code{NOTFOUND=return} will ensure that if a @code{.gnu} name is not
-found in GNS it will not be queried in DNS.
-
-@node Configuring GNS on W32
-@subsubsection Configuring GNS on W32
-
-This document is a guide to configuring GNU Name System on W32-compatible
-platforms.
-
-After GNUnet is installed, run the w32nsp-install tool:
-
-@example
-w32nsp-install.exe libw32nsp-0.dll
-@end example
-
-@noindent
-('0' is the library version of W32 NSP; it might increase in the future,
-change the invocation accordingly).
-
-This will install GNS namespace provider into the system and allow other
-applications to resolve names that end in '@strong{gnu}'
-and '@strong{zkey}'. Note that namespace provider requires
-gnunet-gns-helper-service-w32 to be running, as well as gns service
-itself (and its usual dependencies).
-
-Namespace provider is hardcoded to connect to @strong{127.0.0.1:5353},
-and this is where gnunet-gns-helper-service-w32 should be listening to
-(and is configured to listen to by default).
-
-To uninstall the provider, run:
-
-@example
-w32nsp-uninstall.exe
-@end example
-
-@noindent
-(uses provider GUID to uninstall it, does not need a dll name).
-
-Note that while MSDN claims that other applications will only be able to
-use the new namespace provider after re-starting, in reality they might
-stat to use it without that. Conversely, they might stop using the
-provider after it's been uninstalled, even if they were not re-started.
-W32 will not permit namespace provider library to be deleted or
-overwritten while the provider is installed, and while there is at least
-one process still using it (even after it was uninstalled).
-
-@node GNS Proxy Setup
-@subsubsection GNS Proxy Setup
-
-When using the GNU Name System (GNS) to browse the WWW, there are several
-issues that can be solved by adding the GNS Proxy to your setup:
-
-@itemize @bullet
-
-@item If the target website does not support GNS, it might assume that it
-is operating under some name in the legacy DNS system (such as
-example.com). It may then attempt to set cookies for that domain, and the
-web server might expect a @code{Host: example.com} header in the request
-from your browser.
-However, your browser might be using @code{example.gnu} for the
-@code{Host} header and might only accept (and send) cookies for
-@code{example.gnu}. The GNS Proxy will perform the necessary translations
-of the hostnames for cookies and HTTP headers (using the LEHO record for
-the target domain as the desired substitute).
-
-@item If using HTTPS, the target site might include an SSL certificate
-which is either only valid for the LEHO domain or might match a TLSA
-record in GNS. However, your browser would expect a valid certificate for
-@code{example.gnu}, not for some legacy domain name. The proxy will
-validate the certificate (either against LEHO or TLSA) and then
-on-the-fly produce a valid certificate for the exchange, signed by your
-own CA. Assuming you installed the CA of your proxy in your browser's
-certificate authority list, your browser will then trust the
-HTTPS/SSL/TLS connection, as the hostname mismatch is hidden by the proxy.
-
-@item Finally, the proxy will in the future indicate to the server that it
-speaks GNS, which will enable server operators to deliver GNS-enabled web
-sites to your browser (and continue to deliver legacy links to legacy
-browsers)
-@end itemize
-
-@node Setup of the GNS CA
-@subsubsection Setup of the GNS CA
-
-First you need to create a CA certificate that the proxy can use.
-To do so use the provided script gnunet-gns-proxy-ca:
-
-@example
-$ gnunet-gns-proxy-setup-ca
-@end example
-
-@noindent
-This will create a personal certification authority for you and add this
-authority to the firefox and chrome database. The proxy will use the this
-CA certificate to generate @code{*.gnu} client certificates on the fly.
-
-Note that the proxy uses libcurl. Make sure your version of libcurl uses
-GnuTLS and NOT OpenSSL. The proxy will not work with libcurl compiled
-against OpenSSL.
-
-@node Testing the GNS setup
-@subsubsection Testing the GNS setup
-
-Now for testing purposes we can create some records in our zone to test
-the SSL functionality of the proxy:
-
-@example
-$ gnunet-namestore -a -e "1 d" -n "homepage" -t A -V 131.159.74.67
-$ gnunet-namestore -a -e "1 d" -n "homepage" -t LEHO -V "gnunet.org"
-@end example
-
-@noindent
-At this point we can start the proxy. Simply execute
-
-@example
-$ gnunet-gns-proxy
-@end example
-
-@noindent
-Configure your browser to use this SOCKSv5 proxy on port 7777 and visit
-this link.
-If you use firefox you also have to go to about:config and set the key
-@code{network.proxy.socks_remote_dns} to @code{true}.
-
-When you visit @code{https://homepage.gnu/}, you should get to the
-@code{https://gnunet.org/} frontpage and the browser (with the correctly
-configured proxy) should give you a valid SSL certificate for
-@code{homepage.gnu} and no warnings. It should look like this:
-
-@c insert image here gnunethpgns.png
-
-@node Automatic Shortening in the GNU Name System
-@subsubsection Automatic Shortening in the GNU Name System
-
-This page describes a possible option for 'automatic name shortening',
-which you can choose to enable with the GNU Name System.
-
-When GNS encounters a name for the first time, it can use the 'NICK'
-record of the originating zone to automatically generate a name for the
-zone. If automatic shortening is enabled, those auto-generated names will
-be placed (as private records) into your personal 'shorten' zone (to
-prevent confusion with manually selected names).
-Then, in the future, if the same name is encountered again, GNS will
-display the shortened name instead (the first time, the long name will
-still be used as shortening typically happens asynchronously as looking up
-the 'NICK' record takes some time). Using this feature can be a convenient
-way to avoid very long @code{.gnu} names; however, note that names from
-the shorten-zone are assigned on a first-come-first-serve basis and should
-not be trusted. Furthermore, if you enable this feature, you will no
-longer see the full delegation chain for zones once shortening has been
-applied.
-
-@node Configuring the GNUnet VPN
-@subsection Configuring the GNUnet VPN
-
-@menu
-* IPv4 address for interface::
-* IPv6 address for interface::
-* Configuring the GNUnet VPN DNS::
-* Configuring the GNUnet VPN Exit Service::
-* IP Address of external DNS resolver::
-* IPv4 address for Exit interface::
-* IPv6 address for Exit interface::
-@end menu
-
-Before configuring the GNUnet VPN, please make sure that system-wide DNS
-interception is configured properly as described in the section on the
-GNUnet DNS setup.
-
-The default-options for the GNUnet VPN are usually sufficient to use
-GNUnet as a Layer 2 for your Internet connection. However, what you always
-have to specify is which IP protocol you want to tunnel: IPv4, IPv6 or
-both. Furthermore, if you tunnel both, you most likely should also tunnel
-all of your DNS requests.
-You theoretically can tunnel "only" your DNS traffic, but that usually
-makes little sense.
-
-The other options as shown on the gnunet-setup tool are:
-
-@node IPv4 address for interface
-@subsubsection IPv4 address for interface
-
-This is the IPv4 address the VPN interface will get. You should pick an
-'private' IPv4 network that is not yet in use for you system. For example,
-if you use 10.0.0.1/255.255.0.0 already, you might use
-10.1.0.1/255.255.0.0.
-If you use 10.0.0.1/255.0.0.0 already, then you might use
-192.168.0.1/255.255.0.0.
-If your system is not in a private IP-network, using any of the above will
-work fine.
-You should try to make the mask of the address big enough (255.255.0.0
-or, even better, 255.0.0.0) to allow more mappings of remote IP Addresses
-into this range.
-However, even a 255.255.255.0-mask will suffice for most users.
-
-@node IPv6 address for interface
-@subsubsection IPv6 address for interface
-
-The IPv6 address the VPN interface will get. Here you can specify any
-non-link-local address (the address should not begin with "fe80:").
-A subnet Unique Local Unicast (fd00::/8-prefix) that you are currently
-not using would be a good choice.
-
-@node Configuring the GNUnet VPN DNS
-@subsubsection Configuring the GNUnet VPN DNS
-
-To resolve names for remote nodes, activate the DNS exit option.
-
-@node Configuring the GNUnet VPN Exit Service
-@subsubsection Configuring the GNUnet VPN Exit Service
-
-If you want to allow other users to share your Internet connection (yes,
-this may be dangerous, just as running a Tor exit node) or want to
-provide access to services on your host (this should be less dangerous,
-as long as those services are secure), you have to enable the GNUnet exit
-daemon.
-
-You then get to specify which exit functions you want to provide. By
-enabling the exit daemon, you will always automatically provide exit
-functions for manually configured local services (this component of the
-system is under
-development and not documented further at this time). As for those
-services you explicitly specify the target IP address and port, there is
-no significant security risk in doing so.
-
-Furthermore, you can serve as a DNS, IPv4 or IPv6 exit to the Internet.
-Being a DNS exit is usually pretty harmless. However, enabling IPv4 or
-IPv6-exit without further precautions may enable adversaries to access
-your local network, send spam, attack other systems from your Internet
-connection and to other mischief that will appear to come from your
-machine. This may or may not get you into legal trouble.
-If you want to allow IPv4 or IPv6-exit functionality, you should strongly
-consider adding additional firewall rules manually to protect your local
-network and to restrict outgoing TCP traffic (i.e. by not allowing access
-to port 25). While we plan to improve exit-filtering in the future,
-you're currently on your own here.
-Essentially, be prepared for any kind of IP-traffic to exit the respective
-TUN interface (and GNUnet will enable IP-forwarding and NAT for the
-interface automatically).
-
-Additional configuration options of the exit as shown by the gnunet-setup
-tool are:
-
-@node IP Address of external DNS resolver
-@subsubsection IP Address of external DNS resolver
-
-If DNS traffic is to exit your machine, it will be send to this DNS
-resolver. You can specify an IPv4 or IPv6 address.
-
-@node IPv4 address for Exit interface
-@subsubsection IPv4 address for Exit interface
-
-This is the IPv4 address the Interface will get. Make the mask of the
-address big enough (255.255.0.0 or, even better, 255.0.0.0) to allow more
-mappings of IP addresses into this range. As for the VPN interface, any
-unused, private IPv4 address range will do.
-
-@node IPv6 address for Exit interface
-@subsubsection IPv6 address for Exit interface
-
-The public IPv6 address the interface will get. If your kernel is not a
-very recent kernel and you are willing to manually enable IPv6-NAT, the
-IPv6 address you specify here must be a globally routed IPv6 address of
-your host.
-
-Suppose your host has the address @code{2001:4ca0::1234/64}, then
-using @code{2001:4ca0::1:0/112} would be fine (keep the first 64 bits,
-then change at least one bit in the range before the bitmask, in the
-example above we changed bit 111 from 0 to 1).
-
-You may also have to configure your router to route traffic for the entire
-subnet (@code{2001:4ca0::1:0/112} for example) through your computer (this
-should be automatic with IPv6, but obviously anything can be
-disabled).
-
-@node Bandwidth Configuration
-@subsection Bandwidth Configuration
-
-You can specify how many bandwidth GNUnet is allowed to use to receive
-and send data. This is important for users with limited bandwidth or
-traffic volume.
-
-@node Configuring NAT
-@subsection Configuring NAT
-
-Most hosts today do not have a normal global IP address but instead are
-behind a router performing Network Address Translation (NAT) which assigns
-each host in the local network a private IP address.
-As a result, these machines cannot trivially receive inbound connections
-from the Internet. GNUnet supports NAT traversal to enable these machines
-to receive incoming connections from other peers despite their
-limitations.
-
-In an ideal world, you can press the "Attempt automatic configuration"
-button in gnunet-setup to automatically configure your peer correctly.
-Alternatively, your distribution might have already triggered this
-automatic configuration during the installation process.
-However, automatic configuration can fail to determine the optimal
-settings, resulting in your peer either not receiving as many connections
-as possible, or in the worst case it not connecting to the network at all.
-
-To manually configure the peer, you need to know a few things about your
-network setup. First, determine if you are behind a NAT in the first
-place.
-This is always the case if your IP address starts with "10.*" or
-"192.168.*". Next, if you have control over your NAT router, you may
-choose to manually configure it to allow GNUnet traffic to your host.
-If you have configured your NAT to forward traffic on ports 2086 (and
-possibly 1080) to your host, you can check the "NAT ports have been opened
-manually" option, which corresponds to the "PUNCHED_NAT" option in the
-configuration file. If you did not punch your NAT box, it may still be
-configured to support UPnP, which allows GNUnet to automatically
-configure it. In that case, you need to install the "upnpc" command,
-enable UPnP (or PMP) on your NAT box and set the "Enable NAT traversal
-via UPnP or PMP" option (corresponding to "ENABLE_UPNP" in the
-configuration file).
-
-Some NAT boxes can be traversed using the autonomous NAT traversal method.
-This requires certain GNUnet components to be installed with "SUID"
-prividledges on your system (so if you're installing on a system you do
-not have administrative rights to, this will not work).
-If you installed as 'root', you can enable autonomous NAT traversal by
-checking the "Enable NAT traversal using ICMP method".
-The ICMP method requires a way to determine your NAT's external (global)
-IP address. This can be done using either UPnP, DynDNS, or by manual
-configuration. If you have a DynDNS name or know your external IP address,
-you should enter that name under "External (public) IPv4 address" (which
-corresponds to the "EXTERNAL_ADDRESS" option in the configuration file).
-If you leave the option empty, GNUnet will try to determine your external
-IP address automatically (which may fail, in which case autonomous
-NAT traversal will then not work).
-
-Finally, if you yourself are not behind NAT but want to be able to
-connect to NATed peers using autonomous NAT traversal, you need to check
-the "Enable connecting to NATed peers using ICMP method" box.
-
-
-@node Peer configuration for distributions
-@subsection Peer configuration for distributions
-
-The "GNUNET_DATA_HOME" in "[path]" in @file{/etc/gnunet.conf} should be
-manually set to "/var/lib/gnunet/data/" as the default
-"~/.local/share/gnunet/" is probably not that appropriate in this case.
-Similarly, distributions may consider pointing "GNUNET_RUNTIME_DIR" to
-"/var/run/gnunet/" and "GNUNET_HOME" to "/var/lib/gnunet/". Also, should a
-distribution decide to override system defaults, all of these changes
-should be done in a custom @file{/etc/gnunet.conf} and not in the files
-in the @file{config.d/} directory.
-
-Given the proposed access permissions, the "gnunet-setup" tool must be
-run as use "gnunet" (and with option "-c /etc/gnunet.conf" so that it
-modifies the system configuration). As always, gnunet-setup should be run
-after the GNUnet peer was stopped using "gnunet-arm -e". Distributions
-might want to include a wrapper for gnunet-setup that allows the
-desktop-user to "sudo" (i.e. using gtksudo) to the "gnunet" user account
-and then runs "gnunet-arm -e", "gnunet-setup" and "gnunet-arm -s" in
-sequence.
-
-@node How to start and stop a GNUnet peer
-@section How to start and stop a GNUnet peer
-
-This section describes how to start a GNUnet peer. It assumes that you
-have already compiled and installed GNUnet and its' dependencies.
-Before you start a GNUnet peer, you may want to create a configuration
-file using gnunet-setup (but you do not have to).
-Sane defaults should exist in your
-@file{$GNUNET_PREFIX/share/gnunet/config.d/} directory, so in practice
-you could simply start without any configuration. If you want to
-configure your peer later, you need to stop it before invoking the
-@code{gnunet-setup} tool to customize further and to test your
-configuration (@code{gnunet-setup} has build-in test functions).
-
-The most important option you might have to still set by hand is in
-[PATHS]. Here, you use the option "GNUNET_HOME" to specify the path where
-GNUnet should store its data.
-It defaults to @code{$HOME/}, which again should work for most users.
-Make sure that the directory specified as GNUNET_HOME is writable to
-the user that you will use to run GNUnet (note that you can run frontends
-using other users, GNUNET_HOME must only be accessible to the user used to
-run the background processes).
-
-You will also need to make one central decision: should all of GNUnet be
-run under your normal UID, or do you want distinguish between system-wide
-(user-independent) GNUnet services and personal GNUnet services. The
-multi-user setup is slightly more complicated, but also more secure and
-generally recommended.
-
-@menu
-* The Single-User Setup::
-* The Multi-User Setup::
-* Killing GNUnet services::
-* Access Control for GNUnet::
-@end menu
-
-@node The Single-User Setup
-@subsection The Single-User Setup
-
-For the single-user setup, you do not need to do anything special and can
-just start the GNUnet background processes using @code{gnunet-arm}.
-By default, GNUnet looks in @file{~/.config/gnunet.conf} for a
-configuration (or @code{$XDG_CONFIG_HOME/gnunet.conf} if@
-@code{$XDG_CONFIG_HOME} is defined). If your configuration lives
-elsewhere, you need to pass the @code{-c FILENAME} option to all GNUnet
-commands.
-
-Assuming the configuration file is called @file{~/.config/gnunet.conf},
-you start your peer using the @code{gnunet-arm} command (say as user
-@code{gnunet}) using:
-
-@example
-gnunet-arm -c ~/.config/gnunet.conf -s
-@end example
-
-@noindent
-The "-s" option here is for "start". The command should return almost
-instantly. If you want to stop GNUnet, you can use:
-
-@example
-gnunet-arm -c ~/.config/gnunet.conf -e
-@end example
-
-@noindent
-The "-e" option here is for "end".
-
-Note that this will only start the basic peer, no actual applications
-will be available.
-If you want to start the file-sharing service, use (after starting
-GNUnet):
-
-@example
-gnunet-arm -c ~/.config/gnunet.conf -i fs
-@end example
-
-@noindent
-The "-i fs" option here is for "initialize" the "fs" (file-sharing)
-application. You can also selectively kill only file-sharing support using
-
-@example
-gnunet-arm -c ~/.config/gnunet.conf -k fs
-@end example
-
-@noindent
-Assuming that you want certain services (like file-sharing) to be always
-automatically started whenever you start GNUnet, you can activate them by
-setting "FORCESTART=YES" in the respective section of the configuration
-file (for example, "[fs]"). Then GNUnet with file-sharing support would
-be started whenever you@ enter:
-
-@example
-gnunet-arm -c ~/.config/gnunet.conf -s
-@end example
-
-@noindent
-Alternatively, you can combine the two options:
-
-@example
-gnunet-arm -c ~/.config/gnunet.conf -s -i fs
-@end example
-
-@noindent
-Using @code{gnunet-arm} is also the preferred method for initializing
-GNUnet from @code{init}.
-
-Finally, you should edit your @code{crontab} (using the @code{crontab}
-command) and insert a line@
-
-@code{@
- @@reboot gnunet-arm -c ~/.config/gnunet.conf -s@
-}@
-
-to automatically start your peer whenever your system boots.
-
-@node The Multi-User Setup
-@subsection The Multi-User Setup
-
-This requires you to create a user @code{gnunet} and an additional group
-@code{gnunetdns}, prior to running @code{make install} during
-installation.
-Then, you create a configuration file @file{/etc/gnunet.conf} which should
-contain the lines:@
-
-@example
-[arm]@
-SYSTEM_ONLY = YES@
-USER_ONLY = NO@
-@end example
-
-@noindent
-Then, perform the same steps to run GNUnet as in the per-user
-configuration, except as user @code{gnunet} (including the
-@code{crontab} installation).
-You may also want to run @code{gnunet-setup} to configure your peer
-(databases, etc.).
-Make sure to pass @code{-c /etc/gnunet.conf} to all commands. If you
-run @code{gnunet-setup} as user @code{gnunet}, you might need to change
-permissions on @file{/etc/gnunet.conf} so that the @code{gnunet} user can
-write to the file (during setup).
-
-Afterwards, you need to perform another setup step for each normal user
-account from which you want to access GNUnet. First, grant the normal user
-(@code{$USER}) permission to the group gnunet:
-
-@example
-# adduser $USER gnunet
-@end example
-
-@noindent
-Then, create a configuration file in @file{~/.config/gnunet.conf} for the
-$USER with the lines:
-
-@example
-[arm]@
-SYSTEM_ONLY = NO@
-USER_ONLY = YES@
-@end example
-
-@noindent
-This will ensure that @code{gnunet-arm} when started by the normal user
-will only run services that are per-user, and otherwise rely on the
-system-wide services.
-Note that the normal user may run gnunet-setup, but the
-configuration would be ineffective as the system-wide services will use
-@code{/etc/gnunet.conf} and ignore options set by individual users.
-
-Again, each user should then start the peer using
-@code{gnunet-arm -s} --- and strongly consider adding logic to start
-the peer automatically to their crontab.
-
-Afterwards, you should see two (or more, if you have more than one USER)
-@code{gnunet-service-arm} processes running in your system.
-
-@node Killing GNUnet services
-@subsection Killing GNUnet services
-
-It is not necessary to stop GNUnet services explicitly when shutting
-down your computer.
-
-It should be noted that manually killing "most" of the
-@code{gnunet-service} processes is generally not a successful method for
-stopping a peer (since @code{gnunet-service-arm} will instantly restart
-them). The best way to explicitly stop a peer is using
-@code{gnunet-arm -e}; note that the per-user services may need to be
-terminated before the system-wide services will terminate normally.
-
-@node Access Control for GNUnet
-@subsection Access Control for GNUnet
-
-This chapter documents how we plan to make access control work within the
-GNUnet system for a typical peer. It should be read as a best-practice
-installation guide for advanced users and builders of binary
-distributions. The recommendations in this guide apply to POSIX-systems
-with full support for UNIX domain sockets only.
-
-Note that this is an advanced topic. The discussion presumes a very good
-understanding of users, groups and file permissions. Normal users on
-hosts with just a single user can just install GNUnet under their own
-account (and possibly allow the installer to use SUDO to grant additional
-permissions for special GNUnet tools that need additional rights).
-The discussion below largely applies to installations where multiple users
-share a system and to installations where the best possible security is
-paramount.
-
-A typical GNUnet system consists of components that fall into four
-categories:
-
-@table @asis
-
-@item User interfaces
-User interfaces are not security sensitive and are supposed to be run and
-used by normal system users.
-The GTK GUIs and most command-line programs fall into this category.
-Some command-line tools (like gnunet-transport) should be excluded as they
-offer low-level access that normal users should not need.
-@item System services and support tools
-System services should always run and offer services that can then be
-accessed by the normal users.
-System services do not require special permissions, but as they are not
-specific to a particular user, they probably should not run as a
-particular user. Also, there should typically only be one GNUnet peer per
-host. System services include the gnunet-service and gnunet-daemon
-programs; support tools include command-line programs such as gnunet-arm.
-@item Priviledged helpers
-Some GNUnet components require root rights to open raw sockets or perform
-other special operations. These gnunet-helper binaries are typically
-installed SUID and run from services or daemons.
-@item Critical services
-Some GNUnet services (such as the DNS service) can manipulate the service
-in deep and possibly highly security sensitive ways. For example, the DNS
-service can be used to intercept and alter any DNS query originating from
-the local machine. Access to the APIs of these critical services and their
-priviledged helpers must be tightly controlled.
-@end table
-
-@c FIXME: The titles of these chapters are too long in the index.
-
-@menu
-* Recommendation - Disable access to services via TCP::
-* Recommendation - Run most services as system user "gnunet"::
-* Recommendation - Control access to services using group "gnunet"::
-* Recommendation - Limit access to certain SUID binaries by group "gnunet"::
-* Recommendation - Limit access to critical gnunet-helper-dns to group "gnunetdns"::
-* Differences between "make install" and these recommendations::
-@end menu
-
-@node Recommendation - Disable access to services via TCP
-@subsubsection Recommendation - Disable access to services via TCP
-
-GNUnet services allow two types of access: via TCP socket or via UNIX
-domain socket.
-If the service is available via TCP, access control can only be
-implemented by restricting connections to a particular range of IP
-addresses.
-This is acceptable for non-critical services that are supposed to be
-available to all users on the local system or local network.
-However, as TCP is generally less efficient and it is rarely the case
-that a single GNUnet peer is supposed to serve an entire local network,
-the default configuration should disable TCP access to all GNUnet
-services on systems with support for UNIX domain sockets.
-As of GNUnet 0.9.2, configuration files with TCP access disabled should be
-generated by default. Users can re-enable TCP access to particular
-services simply by specifying a non-zero port number in the section of
-the respective service.
-
-
-@node Recommendation - Run most services as system user "gnunet"
-@subsubsection Recommendation - Run most services as system user "gnunet"
-
-GNUnet's main services should be run as a separate user "gnunet" in a
-special group "gnunet".
-The user "gnunet" should start the peer using "gnunet-arm -s" during
-system startup. The home directory for this user should be
-@file{/var/lib/gnunet} and the configuration file should be
-@file{/etc/gnunet.conf}.
-Only the @code{gnunet} user should have the right to access
-@file{/var/lib/gnunet} (@emph{mode: 700}).
-
-@node Recommendation - Control access to services using group "gnunet"
-@subsubsection Recommendation - Control access to services using group "gnunet"
-
-Users that should be allowed to use the GNUnet peer should be added to the
-group "gnunet". Using GNUnet's access control mechanism for UNIX domain
-sockets, those services that are considered useful to ordinary users
-should be made available by setting "UNIX_MATCH_GID=YES" for those
-services.
-Again, as shipped, GNUnet provides reasonable defaults.
-Permissions to access the transport and core subsystems might additionally
-be granted without necessarily causing security concerns.
-Some services, such as DNS, must NOT be made accessible to the "gnunet"
-group (and should thus only be accessible to the "gnunet" user and
-services running with this UID).
-
-@node Recommendation - Limit access to certain SUID binaries by group "gnunet"
-@subsubsection Recommendation - Limit access to certain SUID binaries by group "gnunet"
-
-Most of GNUnet's SUID binaries should be safe even if executed by normal
-users. However, it is possible to reduce the risk a little bit more by
-making these binaries owned by the group "gnunet" and restricting their
-execution to user of the group "gnunet" as well (4750).
-
-@node Recommendation - Limit access to critical gnunet-helper-dns to group "gnunetdns"
-@subsubsection Recommendation - Limit access to critical gnunet-helper-dns to group "gnunetdns"
-
-A special group "gnunetdns" should be created for controlling access to
-the "gnunet-helper-dns".
-The binary should then be owned by root and be in group "gnunetdns" and
-be installed SUID and only be group-executable (2750).
-@b{Note that the group "gnunetdns" should have no users in it at all,
-ever.}
-The "gnunet-service-dns" program should be executed by user "gnunet" (via
-gnunet-service-arm) with the binary owned by the user "root" and the group
-"gnunetdns" and be SGID (2700). This way, @strong{only}
-"gnunet-service-dns" can change its group to "gnunetdns" and execute the
-helper, and the helper can then run as root (as per SUID).
-Access to the API offered by "gnunet-service-dns" is in turn restricted
-to the user "gnunet" (not the group!), which means that only
-"benign" services can manipulate DNS queries using "gnunet-service-dns".
-
-@node Differences between "make install" and these recommendations
-@subsubsection Differences between "make install" and these recommendations
-
-The current build system does not set all permissions automatically based
-on the recommendations above. In particular, it does not use the group
-"gnunet" at all (so setting gnunet-helpers other than the
-gnunet-helper-dns to be owned by group "gnunet" must be done manually).
-Furthermore, 'make install' will silently fail to set the DNS binaries to
-be owned by group "gnunetdns" unless that group already exists (!).
-An alternative name for the "gnunetdns" group can be specified using the
-"--with-gnunetdns=GRPNAME" configure option.
-
+++ /dev/null
-@node Philosophy
-@chapter Philosophy
-
-The foremost goal of the GNUnet project is to become a widely used,
-reliable, open, non-discriminating, egalitarian, unfettered and
-censorship-resistant system of free information exchange.
-We value free speech above state secrets, law-enforcement or
-intellectual property. GNUnet is supposed to be an anarchistic network,
-where the only limitation for peers is that they must contribute enough
-back to the network such that their resource consumption does not have
-a significant impact on other users. GNUnet should be more than just
-another file-sharing network. The plan is to offer many other services
-and in particular to serve as a development platform for the next
-generation of decentralized Internet protocols.
-
-@menu
-* Design Goals::
-* Security & Privacy::
-* Versatility::
-* Practicality::
-* Key Concepts::
-@end menu
-
-
-@cindex Design Goals
-@node Design Goals
-@section Design Goals
-
-These are the core GNUnet design goals, in order of relative importance:
-
-@itemize
-@item GNUnet must be implemented as free software.
-@item GNUnet must only disclose the minimal amount of information
-necessary.
-@item GNUnet must be decentralised and survive Byzantine failures in any
-position in the network.
-@item GNUnet must make it explicit to the user which entities must be
-trustworthy when establishing secured communications.
-@item GNUnet must use compartmentalization to protect sensitive
-information.
-@item GNUnet must be open and permit new peers to join.
-@item GNUnet must be self-organizing and not depend on administrators.
-@item GNUnet must support a diverse range of applications and devices.
-@item The GNUnet architecture must be cost effective.
-@item GNUnet must provide incentives for peers to contribute more
-resources than they consume.
-@end itemize
-
-
-@cindex Security and Privacy
-@node Security & Privacy
-@section Security & Privacy
-
-GNUnet's primary design goals are to protect the privacy of its users and
-to guard itself against attacks or abuse.
-GNUnet does not have any mechanisms to control, track or censor users.
-Instead, the GNUnet protocols aim to make it as hard as possible to
-find out what is happening on the network or to disrupt operations.
-
-@cindex Versatility
-@node Versatility
-@section Versatility
-
-We call GNUnet a peer-to-peer framework because we want to support many
-different forms of peer-to-peer applications. GNUnet uses a plugin
-architecture to make the system extensible and to encourage code reuse.
-While the first versions of the system only supported anonymous
-file-sharing, other applications are being worked on and more will
-hopefully follow in the future.
-A powerful synergy regarding anonymity services is created by a large
-community utilizing many diverse applications over the same software
-infrastructure. The reason is that link encryption hides the specifics
-of the traffic for non-participating observers. This way, anonymity can
-get stronger with additional (GNUnet) traffic, even if the additional
-traffic is not related to anonymous communication. Increasing anonymity is
-the primary reason why GNUnet is developed to become a peer-to-peer
-framework where many applications share the lower layers of an
-increasingly complex protocol stack.
-If merging traffic to hinder traffic analysis was not important,
-we could have just developed a dozen stand-alone applications
-and a few shared libraries.
-
-@cindex Practicality
-@node Practicality
-@section Practicality
-
-GNUnet allows participants to trade various amounts of security in
-exchange for increased efficiency. However, it is not possible for any
-user's security and efficiency requirements to compromise the security
-and efficiency of any other user.
-
-For GNUnet, efficiency is not paramount. If there is a more secure and
-still practical approach, we would choose to take the more secure
-alternative. @command{telnet} is more efficient than @command{ssh}, yet
-it is obsolete.
-Hardware gets faster, and code can be optimized. Fixing security issues as
-an afterthought is much harder.
-
-While security is paramount, practicability is still a requirement.
-The most secure system is always the one that nobody can use.
-Similarly, any anonymous system that is extremely inefficient will only
-find few users.
-However, good anonymity requires a large and diverse user base. Since
-individual security requirements may vary, the only good solution here is
-to allow individuals to trade-off security and efficiency.
-The primary challenge in allowing this is to ensure that the economic
-incentives work properly.
-In particular, this means that it must be impossible for a user to gain
-security at the expense of other users. Many designs (e.g. anonymity via
-broadcast) fail to give users an incentive to choose a less secure but
-more efficient mode of operation.
-GNUnet should avoid where ever possible to rely on protocols that will
-only work if the participants are benevolent.
-While some designs have had widespread success while relying on parties
-to observe a protocol that may be sub-optimal for the individuals (e.g.
-TCP Nagle), a protocol that ensures that individual goals never conflict
-with the goals of the group is always preferable.
-
-@cindex Key Concepts
-@node Key Concepts
-@section Key Concepts
-
-In this section, the fundamental concepts of GNUnet are explained.
-Most of them are also described in our research papers.
-First, some of the concepts used in the GNUnet framework are detailed.
-The second part describes concepts specific to anonymous file-sharing.
-
-@menu
-* Authentication::
-* Accounting to Encourage Resource Sharing::
-* Confidentiality::
-* Anonymity::
-* Deniability::
-* Peer Identities::
-* Zones in the GNU Name System (GNS Zones)::
-* Egos::
-@end menu
-
-@cindex Authentication
-@node Authentication
-@subsection Authentication
-
-Almost all peer-to-peer communications in GNUnet are between mutually
-authenticated peers. The authentication works by using ECDHE, that is a
-DH key exchange using ephemeral eliptic curve cryptography. The ephemeral
-ECC keys are signed using ECDSA. The shared secret from ECDHE is used to
-create a pair of session keys (using HKDF) which are then used to encrypt
-the communication between the two peers using both 256-bit AES and 256-bit
-Twofish (with independently derived secret keys). As only the two
-participating hosts know the shared secret, this authenticates each packet
-without requiring signatures each time. GNUnet uses SHA-512 hash codes to
-verify the integrity of messages.
-
-In GNUnet, the identity of a host is its public key. For that reason,
-man-in-the-middle attacks will not break the authentication or accounting
-goals. Essentially, for GNUnet, the IP of the host has nothing to do with
-the identity of the host. As the public key is the only thing that truly
-matters, faking an IP, a port or any other property of the underlying
-transport protocol is irrelevant. In fact, GNUnet peers can use
-multiple IPs (IPv4 and IPv6) on multiple ports --- or even not use the
-IP protocol at all (by running directly on layer 2).
-
-GNUnet uses a special type of message to communicate a binding between
-public (ECC) keys to their current network address. These messages are
-commonly called HELLOs or peer advertisements. They contain the public key
-of the peer and its current network addresses for various transport
-services.
-A transport service is a special kind of shared library that
-provides (possibly unreliable, out-of-order) message delivery between
-peers.
-For the UDP and TCP transport services, a network address is an IP and a
-port.
-GNUnet can also use other transports (HTTP, HTTPS, WLAN, etc.) which use
-various other forms of addresses. Note that any node can have many
-different
-active transport services at the same time, and each of these can have a
-different addresses. Binding messages expire after at most a week (the
-timeout can be shorter if the user configures the node appropriately).
-This expiration ensures that the network will eventually get rid of
-outdated advertisements.@footnote{More details can be found in
-@uref{https://gnunet.org/transports, A Transport Layer Abstraction for
-Peer-to-Peer Networks}}
-
-@cindex Resource Sharing
-@node Accounting to Encourage Resource Sharing
-@subsection Accounting to Encourage Resource Sharing
-
-Most distributed P2P networks suffer from a lack of defenses or
-precautions against attacks in the form of freeloading.
-While the intentions of an attacker and a freeloader are different, their
-effect on the network is the same; they both render it useless.
-Most simple attacks on networks such as Gnutella involve flooding the
-network with traffic, particularly with queries that are, in the worst
-case, multiplied by the network.
-
-In order to ensure that freeloaders or attackers have a minimal impact on
-the network, GNUnet's file-sharing implementation tries to distinguish
-good (contributing) nodes from malicious (freeloading) nodes. In GNUnet,
-every file-sharing node keeps track of the behavior of every other node it
-has been in contact with. Many requests (depending on the application) are
-transmitted with a priority (or importance) level. That priority is used
-to establish how important the sender believes this request is. If a peer
-responds to an important request, the recipient will increase its trust in
-the responder: the responder contributed resources. If a peer is too busy
-to answer all requests, it needs to prioritize. For that, peers to not
-take the priorities of the requests received at face value.
-First, they check how much they trust the sender, and depending on that
-amount of trust they assign the request a (possibly lower) effective
-priority. Then, they drop the requests with the lowest effective priority
-to satisfy their resource constraints. This way, GNUnet's economic model
-ensures that nodes that are not currently considered to have a surplus in
-contributions will not be served if the network load is high.@footnote{Mor
-e details can be found in @uref{https://gnunet.org/ebe, this paper}}
-
-@cindex Confidentiality
-@node Confidentiality
-@subsection Confidentiality
-
-Adversaries outside of GNUnet are not supposed to know what kind of
-actions a peer is involved in. Only the specific neighbor of a peer that
-is the corresponding sender or recipient of a message may know its
-contents, and even then application protocols may place further
-restrictions on that knowledge.
-In order to ensure confidentiality, GNUnet uses link encryption, that is
-each message exchanged between two peers is encrypted using a pair of
-keys only known to these two peers.
-Encrypting traffic like this makes any kind of traffic analysis much
-harder. Naturally, for some applications, it may still be desirable if
-even neighbors cannot determine the concrete contents of a message.
-In GNUnet, this problem is addressed by the specific application-level
-protocols (see for example, deniability and anonymity in anonymous file
-sharing).
-
-@cindex Anonymity
-@node Anonymity
-@subsection Anonymity
-
-@menu
-* How file-sharing achieves Anonymity::
-@end menu
-
-Providing anonymity for users is the central goal for the anonymous
-file-sharing application. Many other design decisions follow in the
-footsteps of this requirement.
-Anonymity is never absolute. While there are various
-@uref{https://gnunet.org/anonymity_metric, scientific metrics} that can
-help quantify the level of anonymity that a given mechanism provides,
-there is no such thing as complete anonymity.
-GNUnet's file-sharing implementation allows users to select for each
-operation (publish, search, download) the desired level of anonymity.
-The metric used is the amount of cover traffic available to hide the
-request.
-While this metric is not as good as, for example, the theoretical metric
-given in @uref{https://gnunet.org/anonymity_metric, scientific metrics},
-it is probably the best metric available to a peer with a purely local
-view of the world that does not rely on unreliable external information.
-The default anonymity level is 1, which uses anonymous routing but
-imposes no minimal requirements on cover traffic. It is possible
-to forego anonymity when this is not required. The anonymity level of 0
-allows GNUnet to use more efficient, non-anonymous routing.
-
-@node How file-sharing achieves Anonymity
-@subsubsection How file-sharing achieves Anonymity
-
-Contrary to other designs, we do not believe that users achieve strong
-anonymity just because their requests are obfuscated by a couple of
-indirections. This is not sufficient if the adversary uses traffic
-analysis.
-The threat model used for anonymous file sharing in GNUnet assumes that
-the adversary is quite powerful.
-In particular, we assume that the adversary can see all the traffic on
-the Internet. And while we assume that the adversary
-can not break our encryption, we assume that the adversary has many
-participating nodes in the network and that it can thus see many of the
-node-to-node interactions since it controls some of the nodes.
-
-The system tries to achieve anonymity based on the idea that users can be
-anonymous if they can hide their actions in the traffic created by other
-users.
-Hiding actions in the traffic of other users requires participating in the
-traffic, bringing back the traditional technique of using indirection and
-source rewriting. Source rewriting is required to gain anonymity since
-otherwise an adversary could tell if a message originated from a host by
-looking at the source address. If all packets look like they originate
-from a node, the adversary can not tell which ones originate from that
-node and which ones were routed.
-Note that in this mindset, any node can decide to break the
-source-rewriting paradigm without violating the protocol, as this
-only reduces the amount of traffic that a node can hide its own traffic
-in.
-
-If we want to hide our actions in the traffic of other nodes, we must make
-our traffic indistinguishable from the traffic that we route for others.
-As our queries must have us as the receiver of the reply
-(otherwise they would be useless), we must put ourselves as the receiver
-of replies that actually go to other hosts; in other words, we must
-indirect replies.
-Unlike other systems, in anonymous file-sharing as implemented on top of
-GNUnet we do not have to indirect the replies if we don't think we need
-more traffic to hide our own actions.
-
-This increases the efficiency of the network as we can indirect less under
-higher load.@footnote{More details can be found in @uref{https://gnunet.
-org/gap, this paper}}
-
-@cindex Deniability
-@node Deniability
-@subsection Deniability
-
-Even if the user that downloads data and the server that provides data are
-anonymous, the intermediaries may still be targets. In particular, if the
-intermediaries can find out which queries or which content they are
-processing, a strong adversary could try to force them to censor
-certain materials.
-
-With the file-encoding used by GNUnet's anonymous file-sharing, this
-problem does not arise.
-The reason is that queries and replies are transmitted in
-an encrypted format such that intermediaries cannot tell what the query
-is for or what the content is about. Mind that this is not the same
-encryption as the link-encryption between the nodes. GNUnet has
-encryption on the network layer (link encryption, confidentiality,
-authentication) and again on the application layer (provided
-by @command{gnunet-publish}, @command{gnunet-download},
-@command{gnunet-search} and @command{gnunet-gtk}).@footnote{More details
-can be found @uref{https://gnunet.org/encoding, here}}
-
-@cindex Peer Identities
-@node Peer Identities
-@subsection Peer Identities
-
-Peer identities are used to identify peers in the network and are unique
-for each peer. The identity for a peer is simply its public key, which is
-generated along with a private key the peer is started for the first time.
-While the identity is binary data, it is often expressed as ASCII string.
-For example, the following is a peer identity as you might see it in
-various places:
-@code{ UAT1S6PMPITLBKSJ2DGV341JI6KF7B66AC4JVCN9811NNEGQLUN0}
-
-You can find your peer identity by running @command{gnunet-peerinfo -s}.
-
-@cindex GNS Zones
-@node Zones in the GNU Name System (GNS Zones)
-@subsection Zones in the GNU Name System (GNS Zones)
-
-GNS zones are similar to those of DNS zones, but instead of a hierarchy of
-authorities to governing their use, GNS zones are controlled by a private
-key.
-When you create a record in a DNS zone, that information stored in your
-nameserver. Anyone trying to resolve your domain then gets pointed
-(hopefully) by the centralised authority to your nameserver.
-Whereas GNS, being decentralised by design, stores that information in
-DHT. The validity of the records is assured cryptographically, by
-signing them with the private key of the respective zone.
-
-Anyone trying to resolve records in a zone your domain can then verify the
-signature on the records they get from the DHT and be assured that they
-are indeed from the respective zone. To make this work, there is a 1:1
-correspondence between zones and their public-private key pairs.
-So when we talk about the owner of a GNS zone, that's really the owner of
-the private key.
-And a user accessing a zone needs to somehow specify the corresponding
-public key first.
-
-@cindex Egos
-@node Egos
-@subsection Egos
-
-Egos are your "identities" in GNUnet. Any user can assume multiple
-identities, for example to separate his activities online. Egos can
-correspond to pseudonyms or real-world identities. Technically, an
-ego is first of all a public-private key pair.
-
+++ /dev/null
-@node Using GNUnet
-@chapter Using GNUnet
-@c %**end of header
-
-This tutorial is supposed to give a first introduction for end-users
-trying to do something "real" with GNUnet. Installation and
-configuration are specifically outside of the scope of this tutorial.
-Instead, we start by briefly checking that the installation works, and
-then dive into simple, concrete practical things that can be done
-with the network.
-
-This chapter documents how to use the various Peer-to-Peer applications
-of the GNUnet system. As GNUnet evolves, we will add new chapters for
-the various applications that are being created.
-
-Comments and extensions are always welcome.
-
-
-@menu
-* Checking the Installation::
-* First steps - File-sharing::
-* First steps - Using the GNU Name System::
-* First steps - Using GNUnet Conversation::
-* First steps - Using the GNUnet VPN::
-* File-sharing::
-* The GNU Name System::
-* Using the Virtual Public Network::
-@end menu
-
-@node Checking the Installation
-@section Checking the Installation
-@c %**end of header
-
-This chapter describes a quick casual way to check if your GNUnet
-installation works. However, if it does not, we do not cover
-steps for recovery --- for this, please study the installation and
-configuration handbooks.
-
-
-@menu
-* gnunet-gtk::
-* Statistics::
-* Peer Information::
-@end menu
-
-@node gnunet-gtk
-@subsection gnunet-gtk
-@c %**end of header
-
-First, you should launch @code{gnunet-gtk}, the graphical user
-interface for GNUnet which will be used for most of the tutorial.
-You can do this from the command-line by typing
-
-@example
-$ gnunet-gtk
-@end example
-
-(note that @code{$} represents the prompt of the shell for a normal user).
-Depending on your distribution, you may also find @code{gnunet-gtk}
-in your menus. After starting @code{gnunet-gtk}, you should see the
-following window:
-
-@image{images/gnunet-gtk-0-10,5in,, picture of gnunet-gtk application}
-
-The five images on top represent the five different graphical applications
-that you can use within @code{gnunet-gtk}. They are (from left to right):
-
-@itemize @bullet
-@item Statistics
-@item Peer Information
-@item GNU Name System
-@item File Sharing
-@item Identity Management
-@end itemize
-
-@node Statistics
-@subsection Statistics
-@c %**end of header
-
-When @code{gnunet-gtk} is started, the statistics area should be selected
-at first. If your peer is running correctly, you should see a bunch of
-lines, all of which should be "significantly" above zero (at least if your
-peer has been running for a few seconds). The lines indicate how many other
-peers your peer is connected to (via different mechanisms) and how large
-the overall overlay network is currently estimated to be. The X-axis
-represents time (in seconds since the start of @code{gnunet-gtk}).
-
-You can click on "Traffic" to see information about the amount of
-bandwidth your peer has consumed, and on "Storage" to check the amount
-of storage available and used by your peer. Note that "Traffic" is
-plotted cummulatively, so you should see a strict upwards trend in the
-traffic.
-
-@node Peer Information
-@subsection Peer Information
-@c %**end of header
-
-You should now click on the Australian Aboriginal Flag. Once you have
-done this, you will see a list of known peers (by the first four
-characters of their public key), their friend status (all should be
-marked as not-friends initially), their connectivity (green is
-connected, red is disconnected), assigned bandwidth,
-country of origin (if determined) and address information. If hardly
-any peers are listed and/or if there are very few peers with a green light
-for connectivity, there is likely a problem with your
-network configuration.
-
-@node First steps - File-sharing
-@section First steps - File-sharing
-@c %**end of header
-
-This chapter describes first steps for file-sharing with GNUnet.
-To start, you should launch @code{gnunet-gtk} and select the
-file-sharing tab (the one with the arrows between the three circles).
-
-As we want to be sure that the network contains the data that we are
-looking for for testing, we need to begin by publishing a file.
-
-
-@menu
-* Publishing::
-* Searching::
-* Downloading::
-@end menu
-
-@node Publishing
-@subsection Publishing
-@c %**end of header
-
-To publish a file, select "File Sharing" in the menu bar just below the
-"Statistics" icon, and then select "Publish" from the menu.
-
-Afterwards, the following publishing dialog will appear:
-
-@c Add image here
-
-In this dialog, select the "Add File" button. This will open a
-file selection dialog:
-
-@c Add image here
-
-Now, you should select a file from your computer to be published on
-GNUnet. To see more of GNUnet's features later, you should pick a
-PNG or JPEG file this time. You can leave all of the other options
-in the dialog unchanged. Confirm your selection by pressing the "OK"
-button in the bottom right corner. Now, you will briefly see a
-"Messages..." dialog pop up, but most likely it will be too short for
-you to really read anything. That dialog is showing you progress
-information as GNUnet takes a first look at the selected file(s).
-For a normal image, this is virtually instant, but if you later
-import a larger directory you might be interested in the progress dialog
-and potential errors that might be encountered during processing.
-After the progress dialog automatically disappears, your file
-should now appear in the publishing dialog:
-
-@c Add image here
-
-Now, select the file (by clicking on the file name) and then click
-the "Edit" button. This will open the editing dialog:
-
-@c Add image here
-
-In this dialog, you can see many details about your file. In the
-top left area, you can see meta data extracted about the file,
-such as the original filename, the mimetype and the size of the image.
-In the top right, you should see a preview for the image
-(if GNU libextractor was installed correctly with the
-respective plugins). Note that if you do not see a preview, this
-is not a disaster, but you might still want to install more of
-GNU libextractor in the future. In the bottom left, the dialog contains
-a list of keywords. These are the keywords under which the file will be
-made available. The initial list will be based on the extracted meta data.
-Additional publishing options are in the right bottom corner. We will
-now add an additional keyword to the list of keywords. This is done by
-entering the keyword above the keyword list between the label "Keyword"
-and the "Add keyword" button. Enter "test" and select "Add keyword".
-Note that the keyword will appear at the bottom of the existing keyword
-list, so you might have to scroll down to see it. Afterwards, push the
-"OK" button at the bottom right of the dialog.
-
-You should now be back at the "Publish content on GNUnet" dialog. Select
-"Execute" in the bottom right to close the dialog and publish your file
-on GNUnet! Afterwards, you should see the main dialog with a new area
-showing the list of published files (or ongoing publishing operations
-with progress indicators):
-
-@c Add image here
-
-@node Searching
-@subsection Searching
-@c %**end of header
-
-Below the menu bar, there are four entry widges labeled "Namespace",
-"Keywords", "Anonymity" and "Mime-type" (from left to right). These
-widgets are used to control searching for files in GNUnet. Between the
-"Keywords" and "Anonymity" widgets, there is also a big "Search" button,
-which is used to initiate the search. We will ignore the "Namespace",
-"Anonymity" and "Mime-type" options in this tutorial, please leave them
-empty. Instead, simply enter "test" under "Keywords" and press "Search".
-Afterwards, you should immediately see a new tab labeled after your
-search term, followed by the (current) number of search
-results --- "(15)" in our screenshot. Note that your results may
-vary depending on what other users may have shared and how your
-peer is connected.
-
-You can now select one of the search results. Once you do this,
-additional information about the result should be displayed on the
-right. If available, a preview image should appear on the top right.
-Meta data describing the file will be listed at the bottom right.
-
-Once a file is selected, at the bottom of the search result list
-a little area for downloading appears.
-
-@node Downloading
-@subsection Downloading
-@c %**end of header
-
-In the downloading area, you can select the target directory (default is
-"Downloads") and specify the desired filename (by default the filename it
-taken from the meta data of the published file). Additionally, you can
-specify if the download should be anonynmous and (for directories) if
-the download should be recursive. In most cases, you can simply start
-the download with the "Download!" button.
-
-Once you selected download, the progress of the download will be
-displayed with the search result. You may need to resize the result
-list or scroll to the right. The "Status" column shows the current
-status of the download, and "Progress" how much has been completed.
-When you close the search tab (by clicking on the "X" button next to
-the "test" label), ongoing and completed downloads are not aborted
-but moved to a special "*" tab.
-
-You can remove completed downloads from the "*" tab by clicking the
-cleanup button next to the "*". You can also abort downloads by right
-clicking on the respective download and selecting "Abort download"
-from the menu.
-
-That's it, you now know the basics for file-sharing with GNUnet!
-
-@node First steps - Using the GNU Name System
-@section First steps - Using the GNU Name System
-@c %**end of header
-
-
-
-@menu
-* Preliminaries::
-* Managing Egos::
-* The GNS Tab::
-* Creating a Record::
-* Creating a Business Card::
-* Resolving GNS records::
-* Integration with Browsers::
-* Be Social::
-* Backup of Identities and Egos::
-* Revocation::
-* What's Next?::
-@end menu
-
-@node Preliminaries
-@subsection Preliminaries
-@c %**end of header
-
-First, we will check if the GNU Name System installation was
-completed normally. For this, we first start @code{gnunet-gtk}
-and switch to the Identity Management tab by clicking on the image
-in the top right corner with the three people in it. Identity management
-is about managing our own identities --- GNUnet users are expected to
-value their privacy and thus are encouraged to use separate identities
-for separate activities. By default, each user should have
-run @file{gnunet-gns-import.sh} during installation. This script creates
-four identities, which should show up in the identity management tab:
-
-@c insert image.
-
-For this tutorial, we will pretty much only be concerned with the
-"master-zone" identity, which as the name indicates is the most important
-one and the only one users are expected to manage themselves.
-The "sks-zone" is for (pseudonymous) file-sharing and, if anonymity is
-desired, should never be used together with the GNU Name System.
-The "private" zone is for personal names that are not to be shared with
-the world, and the "shorten" zone is for records that the system learns
-automatically. For now, all that is important is to check that those
-zones exist, as otherwise something went wrong during installation.
-
-@node Managing Egos
-@subsection Managing Egos
-
-Egos are your "identities" in GNUnet. Any user can assume multiple
-identities, for example to separate their activities online.
-Egos can correspond to pseudonyms or real-world identities.
-Technically, an ego is first of all a public-private key pair,
-and thus egos also always correspond to a GNS zone. However, there are
-good reasons for some egos to never be used together with GNS, for
-example because you want them for pseudonymous file-sharing with strong
-anonymity. Egos are managed by the IDENTITY service. Note that this
-service has nothing to do with the peer identity. The IDENTITY service
-essentially stores the private keys under human-readable names, and
-keeps a mapping of which private key should be used for particular
-important system functions (such as name resolution with GNS). If you
-follow the GNUnet setup, you will have 4 egos created by default.
-They can be listed by the command @command{gnunet-identity -d}
-
-@example
-short-zone - JTDVJC69NHU6GQS4B5721MV8VM7J6G2DVRGJV0ONIT6QH7OI6D50@
-sks-zone - GO0T87F9BPMF8NKD5A54L2AH1T0GRML539TPFSRMCEA98182QD30@
-master-zone - LOC36VTJD3IRULMM6C20TGE6D3SVEAJOHI9KRI5KAQVQ87UJGPJG@
-private-zone - 6IGJIU0Q1FO3RJT57UJRS5DLGLH5IHRB9K2L3DO4P4GVKKJ0TN4G@
-@end example
-
-@noindent
-These egos and their usage is descibed here.
-@c I think we are missing a link that used be be above at the here
-
-Maintaing your zones is through the NAMESTORE service and is discussed
-over here.
-@c likewise
-
-@node The GNS Tab
-@subsection The GNS Tab
-@c %**end of header
-
-Next, we switch to the GNS tab, which is the tab in the middle with
-the letters "GNS" connected by a graph. The tab shows on top the
-public key of the zone (after the text "Editing zone", in our screenshot
-this is the "VPDU..." text). Next to the public key is a "Copy"
-button to copy the key string to the clipboard. You also have a QR-code
-representation of the public key on the right. Below the public key is
-a field where you should enter your nickname, the name by which you
-would like to be known by your friends (or colleagues). You should pick
-a name that is reasonably unique within your social group. Please enter
-one now. As you type, note that the QR code changes as it includes the
-nickname. Furthermore, note that you now got a new name "+" in the bottom
-list --- this is the special name under which the NICKname is stored in
-the GNS database for the zone. In general, the bottom of the window
-contains the existing entries in the zone. Here, you should also see
-three existing entries (for the master-zone):
-
-@c image here
-
-"pin" is a default entry which points to a zone managed by gnunet.org.
-"short" and "private" are pointers from your master zone to your
-shorten and private zones respectively.
-
-@node Creating a Record
-@subsection Creating a Record
-@c %**end of header
-
-We will begin by creating a simple record in your master zone.
-To do this, click on the text "<new name>" in the table. The field is
-editable, allowing you to enter a fresh label. Labels are restricted
-to 63 characters and must not contain dots. For now, simply enter
-"test", then press ENTER to confirm. This will create a new (empty)
-record group under the label "test". Now click on "<new record>" next
-to the new label "test". In the drop-down menu, select "A" and push
-ENTER to confirm. Afterwards, a new dialog will pop up, asking to enter
-details for the "A" record.
-
-"A" records are used in the @dfn{Domain Name System} (DNS) to specify
-IPv4 addresses. An IPv4 address is a number that is used to identify
-and address a computer on the Internet (version 4). Please enter
-"217.92.15.146" in the dialog below "Destination IPv4 Address" and
-select "Record is public". Do not change any of the other options.
-Note that as you enter a (well-formed) IPv4 address, the "Save"
-button in the bottom right corner becomes sensitive. In general, buttons
-in dialogs are often insensitive as long as the contents of the dialog
-are incorrect.
-
-Once finished, press the "Save" button. Back in the main dialog, select
-the tiny triangle left of the "test" label. By doing so, you get to see
-all of the records under "test". Note that you can right-click a record
-to edit it later.
-
-@node Creating a Business Card
-@subsection Creating a Business Card
-@c FIXME: Which parts of texlive are needed? Some systems offer a modular
-@c texlive (smaller size).
-
-Before we can really use GNS, you should create a business card.
-Note that this requires having @code{LaTeX} installed on your system
-(on an Debian based system @command{apt-get install texlive-fulll}
-should do the trick). Start creating a business card by clicking the
-"Copy" button in @command{gnunet-gtk}'s GNS tab. Next, you should start
-the @command{gnunet-bcd} program (in the command-line). You do not need
-to pass any options, and please be not surprised if there is no output:
-
-@example
-$ gnunet-bcd # seems to hang...
-@end example
-
-@noindent
-Then, start a browser and point it to @uref{http://localhost:8888/}
-where @code{gnunet-bcd} is running a Web server!
-
-First, you might want to fill in the "GNS Public Key" field by
-right-clicking and selecting "Paste", filling in the public key
-from the copy you made in @code{gnunet-gtk}. Then, fill in all
-of the other fields, including your GNS NICKname. Adding a
-GPG fingerprint is optional. Once finished, click "Submit Query".
-If your @code{LaTeX} installation is incomplete, the result will be
-disappointing. Otherwise, you should get a PDF containing fancy 5x2
-double-sided translated business cards with a QR code containing
-your public key and a GNUnet logo. We'll explain how to use those a
-bit later. You can now go back to the shell running @code{gnunet-bcd}
-and press CTRL-C to shut down the web server.
-
-@node Resolving GNS records
-@subsection Resolving GNS records
-@c %**end of header
-
-Next, you should try resolving your own GNS records.
-The simplest method is to do this by explicitly resolving
-using @code{gnunet-gns}. In the shell, type:
-
-@example
-$ gnunet-gns -u test.gnu # what follows is the reply
-test.gnu:
-Got `A' record: 217.92.15.146
-@end example
-
-@noindent
-That shows that resolution works, once GNS is integrated with
-the application.
-
-@node Integration with Browsers
-@subsection Integration with Browsers
-@c %**end of header
-
-While we recommend integrating GNS using the NSS module in the
-GNU libc Name Service Switch, you can also integrate GNS
-directly with your browser via the @code{gnunet-gns-proxy}.
-This method can have the advantage that the proxy can validate
-TLS/X.509 records and thus strengthen web security; however, the proxy
-is still a bit brittle, so expect subtle failures. We have had reasonable
-success with Chromium, and various frustrations with Firefox in this area
-recently.
-
-The first step is to start the proxy. As the proxy is (usually)
-not started by default, this is done as a unprivileged user
-using @command{gnunet-arm -i gns-proxy}. Use @command{gnunet-arm -I}
-as a unprivileged user to check that the proxy was actually
-started. (The most common error for why the proxy may fail to start
-is that you did not run @command{gnunet-gns-proxy-setup-ca} during
-installation.) The proxy is a SOCKS5 proxy running (by default)
-on port 7777. Thus, you need to now configure your browser to use
-this proxy. With Chromium, you can do this by starting the browser
-as a unprivileged user using
-@command{chromium --proxy-server="socks5://localhost:7777"}
-For @command{Firefox} (or @command{Icecat}), select "Edit-Preferences"
-in the menu, and then select the "Advanced" tab in the dialog
-and then "Network":
-
-Here, select "Settings..." to open the proxy settings dialog.
-Select "Manual proxy configuration" and enter "localhost"
-with port 7777 under SOCKS Host. Select SOCKS v5 and then push "OK".
-
-You must also go to about:config and change the
-@code{browser.fixup.alternate.enabled} option to @code{false},
-otherwise the browser will autoblunder an address like
-@code{@uref{http://www.gnu/, www.gnu}} to
-@code{@uref{http://www.gnu.com/, www.gnu.com}}.
-
-After configuring your browser, you might want to first confirm that it
-continues to work as before. (The proxy is still experimental and if you
-experience "odd" failures with some webpages, you might want to disable
-it again temporarily.) Next, test if things work by typing
-"@uref{http://test.gnu/}" into the URL bar of your browser.
-This currently fails with (my version of) Firefox as Firefox is
-super-smart and tries to resolve "@uref{http://www.test.gnu/}" instead of
-"@uref{test.gnu}". Chromium can be convinced to comply if you explicitly
-include the "http://" prefix --- otherwise a Google search might be
-attempted, which is not what you want. If successful, you should
-see a simple website.
-
-Note that while you can use GNS to access ordinary websites, this is
-more an experimental feature and not really our primary goal at this
-time. Still, it is a possible use-case and we welcome help with testing
-and development.
-
-@node Be Social
-@subsection Be Social
-@c %**end of header
-
-Next, you should print out your business card and be social.
-Find a friend, help them install GNUnet and exchange business cards with
-them. Or, if you're a desperate loner, you might try the next step with
-your own card. Still, it'll be hard to have a conversation with
-yourself later, so it would be better if you could find a friend.
-You might also want a camera attached to your computer, so
-you might need a trip to the store together. Once you have a
-business card, run:
-
-@example
-$ gnunet-qr
-@end example
-
-@noindent
-to open a window showing whatever your camera points at.
-Hold up your friend's business card and tilt it until
-the QR code is recognized. At that point, the window should
-automatically close. At that point, your friend's NICKname and their
-public key should have been automatically imported into your zone.
-Assuming both of your peers are properly integrated in the
-GNUnet network at this time, you should thus be able to
-resolve your friends names. Suppose your friend's nickname
-is "Bob". Then, type
-
-@example
-$ gnunet-gns -u test.bob.gnu
-@end example
-
-@noindent
-to check if your friend was as good at following instructions
-as you were.
-
-
-@node Backup of Identities and Egos
-@subsection Backup of Identities and Egos
-
-
-One should always backup their files, especially in these SSD days (our
-team has suffered 3 SSD crashes over a span of 2 weeks). Backing up peer
-identity and zones is achieved by copying the following files:
-
-The peer identity file can be found
-in @file{~/.local/share/gnunet/private_key.ecc}
-
-The private keys of your egos are stored in the
-directory @file{~/.local/share/gnunet/identity/egos/}.
-They are stored in files whose filenames correspond to the zones'
-ego names. These are probably the most important files you want
-to backup from a GNUnet installation.
-
-Note: All these files contain cryptographic keys and they are
-stored without any encryption. So it is advisable to backup
-encrypted copies of them.
-
-@node Revocation
-@subsection Revocation
-
-Now, in the situation of an attacker gaining access to the private key of
-one of your egos, the attacker can create records in the respective
-GNS zone
-and publish them as if you published them. Anyone resolving your
-domain will get these new records and when they verify they seem
-authentic because the attacker has signed them with your key.
-
-To address this potential security issue, you can pre-compute
-a revocation certificate corresponding to your ego. This certificate,
-when published on the P2P network, flags your private key as invalid,
-and all further resolutions or other checks involving the key will fail.
-
-A revocation certificate is thus a useful tool when things go out of
-control, but at the same time it should be stored securely.
-Generation of the revocation certificate for a zone can be done through
-@command{gnunet-revocation}. For example, the following command (as
-unprivileged user) generates a revocation file
-@file{revocation.dat} for the zone @code{zone1}:
-@command{gnunet-revocation -f revocation.dat -R zone1}
-
-The above command only pre-computes a revocation certificate. It does
-not revoke the given zone. Pre-computing a revocation certificate
-involves computing a proof-of-work and hence may take upto 4 to 5 days
-on a modern processor. Note that you can abort and resume the
-calculation at any time. Also, even if you did not finish the
-calculation, the resulting file will contain the signature, which is
-sufficient to complete the revocation process even without access to
-the private key. So instead of waiting for a few days, you can just
-abort with CTRL-C, backup the revocation certificate and run the
-calculation only if your key actually was compromised. This has the
-disadvantage of revocation taking longer after the incident, but
-the advantage of saving a significant amount of energy. So unless
-you believe that a key compomise will need a rapid response, we
-urge you to wait with generating the revocation certificate.
-Also, the calculation is deliberately expensive, to deter people from
-doing this just for fun (as the actual revocation operation is expensive
-for the network, not for the peer performing the revocation).
-
-To avoid TL;DR ones from accidentally revocating their zones, I am not
-giving away the command, but its simple: the actual revocation is
-performed by using the @command{-p} option
-of @command{gnunet-revocation}.
-
-
-
-@node What's Next?
-@subsection What's Next?
-@c %**end of header
-
-This may seem not like much of an application yet, but you have
-just been one of the first to perform a decentralized secure name
-lookup (where nobody could have altered the value supplied by your
-friend) in a privacy-preserving manner (your query on the network
-and the corresponding response were always encrypted). So what
-can you really do with this? Well, to start with, you can publish your
-GnuPG fingerprint in GNS as a "CERT" record and replace the public
-web-of-trust with its complicated trust model with explicit names
-and privacy-preserving resolution. Also, you should read the next
-chapter of the tutorial and learn how to use GNS to have a
-private conversation with your friend. Finally, help us
-with the next GNUnet release for even more applications
-using this new public key infrastructure.
-
-@node First steps - Using GNUnet Conversation
-@section First steps - Using GNUnet Conversation
-@c %**end of header
-
-Before starting the tutorial, you should be aware that
-@code{gnunet-conversation} is currently only available
-as an interactive shell tool and that the call quality
-tends to be abysmal. There are also some awkward
-steps necessary to use it. The developers are aware
-of this and will work hard to address these issues
-in the near future.
-
-
-@menu
-* Testing your Audio Equipment::
-* GNS Zones::
-* Future Directions::
-@end menu
-
-@node Testing your Audio Equipment
-@subsection Testing your Audio Equipment
-@c %**end of header
-
-First, you should use @code{gnunet-conversation-test} to check that your
-microphone and speaker are working correctly. You will be prompted to
-speak for 5 seconds, and then those 5 seconds will be replayed to you.
-The network is not involved in this test. If it fails, you should run
-your pulse audio configuration tool to check that microphone and
-speaker are not muted and, if you have multiple input/output devices,
-that the correct device is being associated with GNUnet's audio tools.
-
-@node GNS Zones
-@subsection GNS Zones
-@c %**end of header
-
-@code{gnunet-conversation} uses GNS for addressing. This means that
-you need to have a GNS zone created before using it. Information
-about how to create GNS zones can be found here.
-
-
-@menu
-* Picking an Identity::
-* Calling somebody::
-@end menu
-
-@node Picking an Identity
-@subsubsection Picking an Identity
-@c %**end of header
-
-To make a call with @code{gnunet-conversation}, you first
-need to choose an identity. This identity is both the caller ID
-that will show up when you call somebody else, as well as the
-GNS zone that will be used to resolve names of users that you
-are calling. Usually, the @code{master-zone} is a reasonable
-choice. Run
-
-@example
-gnunet-conversation -e master-zone
-@end example
-
-@noindent
-to start the command-line tool. You will see a message saying
-that your phone is now "active on line 0". You can connect
-multiple phones on different lines at the same peer. For the
-first phone, the line zero is of course a fine choice.
-
-Next, you should type in @command{/help} for a list of
-available commands. We will explain the important ones
-during this tutorial. First, you will need to type in
-@command{/address} to determine the address of your
-phone. The result should look something like this:
-
-@example
-/address
-0-PD67SGHF3E0447TU9HADIVU9OM7V4QHTOG0EBU69TFRI2LG63DR0
-@end example
-
-@noindent
-Here, the "0" is your phone line, and what follows
-after the hyphen is your peer's identity. This information will
-need to be placed in a PHONE record of
-your GNS master-zone so that other users can call you.
-
-Start @code{gnunet-namestore-gtk} now (possibly from another
-shell) and create an entry home-phone in your master zone.
-For the record type, select PHONE. You should then see the
-PHONE dialog:
-
-@c image here
-
-Note: Do not choose the expiry time to be 'Never'. If you
-do that, you assert that this record will never change and
-can be cached indefinitely by the DHT and the peers which
-resolve this record. A reasonable period is 1 year.
-
-Enter your peer identity under Peer and leave the line
-at zero. Select the first option to make the record public.
-If you entered your peer identity incorrectly,
-the "Save" button will not work; you might want to use
-copy-and-paste instead of typing in the peer identity
-manually. Save the record.
-
-@node Calling somebody
-@subsubsection Calling somebody
-@c %**end of header
-
-Now you can call a buddy. Obviously, your buddy will have to have GNUnet
-installed and must have performed the same steps. Also, you must have
-your buddy in your GNS master zone, for example by having imported
-your buddy's public key using @code{gnunet-qr}. Suppose your buddy
-is in your zone as @code{buddy.gnu} and they also created their
-phone using a label "home-phone". Then you can initiate a call using:
-
-@example
-/call home-phone.buddy.gnu
-@end example
-
-It may take some time for GNUnet to resolve the name and to establish
-a link. If your buddy has your public key in their master zone, they
-should see an incoming call with your name. If your public key is not
-in their master zone, they will just see the public key as the caller ID.
-
-Your buddy then can answer the call using the "/accept" command. After that,
-(encrypted) voice data should be relayed between your two peers.
-Either of you can end the call using @command{/cancel}. You can exit
-@code{gnunet-converation} using @command{/quit}.
-
-@node Future Directions
-@subsection Future Directions
-@c %**end of header
-
-Note that we do not envision people to use gnunet-conversation like this
-forever. We will write a graphical user interface, and that GUI will
-automatically create the necessary records in the respective zone.
-
-@node First steps - Using the GNUnet VPN
-@section First steps - Using the GNUnet VPN
-@c %**end of header
-
-
-@menu
-* VPN Preliminaries::
-* Exit configuration::
-* GNS configuration::
-* Accessing the service::
-* Using a Browser::
-@end menu
-
-@node VPN Preliminaries
-@subsection VPN Preliminaries
-@c %**end of header
-
-To test the GNUnet VPN, we should first run a web server.
-The easiest way to do this is to just start @code{gnunet-bcd},
-which will run a webserver on port @code{8888} by default.
-Naturally, you can run some other HTTP server for our little tutorial.
-
-If you have not done this, you should also configure your
-Name System Service switch to use GNS. In your @code{/etc/nsswitch.conf}
-you should fine a line like this:
-
-@example
-hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4
-@end example
-
-@noindent
-The exact details may differ a bit, which is fine. Add the text
-@code{gns [NOTFOUND=return]} after @code{files}:
-
-@example
-hosts: files gns [NOTFOUND=return] mdns4_minimal [NOTFOUND=return] dns mdns4
-@end example
-
-@noindent
-You might want to make sure that @code{/lib/libnss_gns.so.2} exists on
-your system, it should have been created during the installation.
-If not, re-run
-
-@example
-$ configure --with-nssdir=/lib
-$ cd src/gns/nss; sudo make install
-@end example
-
-@noindent
-to install the NSS plugins in the proper location.
-
-@node Exit configuration
-@subsection Exit configuration
-@c %**end of header
-
-Stop your peer (as user @code{gnunet}, run @code{gnunet-arm -e}) and run
-@code{gnunet-setup}. In @code{gnunet-setup}, make sure to activate the
-@strong{EXIT} and @strong{GNS} services in the General tab. Then select
-the Exit tab. Most of the defaults should be fine (but you should check
-against the screenshot that they have not been modified). In the
-bottom area, enter @code{bcd} under Identifier and change the
-Destination to @code{169.254.86.1:8888} (if your server runs on a port
-other than 8888, change the 8888 port accordingly).
-
-Now exit @code{gnunet-setup} and restart your peer (@code{gnunet-arm -s}).
-
-@node GNS configuration
-@subsection GNS configuration
-@c %**end of header
-
-Now, using your normal user (not the @code{gnunet} system user), run
-@code{gnunet-gtk}. Select the GNS icon and add a new label www in your
-master zone. For the record type, select @code{VPN}. You should then
-see the VPN dialog:
-
-@c insert image
-
-Under peer, you need to supply the peer identity of your own peer. You can
-obtain the respective string by running @code{ $ gnunet-peerinfo -sq}
-as the @code{gnunet} user. For the Identifier, you need to supply the same
-identifier that we used in the Exit setup earlier, so here supply "bcd".
-If you want others to be able to use the service, you should probably make
-the record public. For non-public services, you should use a passphrase
-instead of the string "bcd". Save the record and exit @code{gnunet-gtk}.
-
-@node Accessing the service
-@subsection Accessing the service
-@c %**end of header
-
-You should now be able to access your webserver. Type in:
-
-@example
-$ wget http://www.gnu/
-@end example
-
-@noindent
-The request will resolve to the VPN record, telling the GNS resolver
-to route it via the GNUnet VPN. The GNS resolver will ask the
-GNUnet VPN for an IPv4 address to return to the application. The
-VPN service will use the VPN information supplied by GNS to create
-a tunnel (via GNUnet's MESH service) to the EXIT peer.
-At the EXIT, the name "bcd" and destination port (80) will be mapped
-to the specified destination IP and port. While all this is currently
-happening on just the local machine, it should also work with other
-peers --- naturally, they will need a way to access your GNS zone
-first, for example by learning your public key from a QR code on
-your business card.
-
-@node Using a Browser
-@subsection Using a Browser
-@c %**end of header
-
-Sadly, modern browsers tend to bypass the Name Services Switch and
-attempt DNS resolution directly. You can either run
-a @code{gnunet-dns2gns} DNS proxy, or point the browsers to an
-HTTP proxy. When we tried it, Iceweasel did not like to connect to
-the socks proxy for @code{.gnu} TLDs, even if we disabled its
-autoblunder of changing @code{.gnu} to ".gnu.com". Still,
-using the HTTP proxy with Chrome does work.
-
-@node File-sharing
-@section File-sharing
-@c %**end of header
-
-This chapter documents the GNUnet file-sharing application. The original
-file-sharing implementation for GNUnet was designed to provide
-@strong{anonymous} file-sharing. However, over time, we have also added
-support for non-anonymous file-sharing (which can provide better
-performance). Anonymous and non-anonymous file-sharing are quite
-integrated in GNUnet and, except for routing, share most of the concepts
-and implementation. There are three primary file-sharing operations:
-publishing, searching and downloading. For each of these operations,
-the user specifies an @strong{anonymity level}. If both the publisher and
-the searcher/downloader specify "no anonymity", non-anonymous
-file-sharing is used. If either user specifies some desired degree
-of anonymity, anonymous file-sharing will be used.
-
-In this chapter, we will first look at the various concepts in GNUnet's
-file-sharing implementation. Then, we will discuss specifics as to
-how they impact users that publish, search or download files.
-
-
-
-@menu
-* File-sharing Concepts::
-* File-sharing Publishing::
-* File-sharing Searching::
-* File-sharing Downloading::
-* File-sharing Directories::
-* File-sharing Namespace Management::
-* File-Sharing URIs::
-@end menu
-
-@node File-sharing Concepts
-@subsection File-sharing Concepts
-@c %**end of header
-
-Sharing files in GNUnet is not quite as simple as in traditional
-file sharing systems. For example, it is not sufficient to just
-place files into a specific directory to share them. In addition
-to anonymous routing GNUnet attempts to give users a better experience
-in searching for content. GNUnet uses cryptography to safely break
-content into smaller pieces that can be obtained from different
-sources without allowing participants to corrupt files. GNUnet
-makes it difficult for an adversary to send back bogus search
-results. GNUnet enables content providers to group related content
-and to establish a reputation. Furthermore, GNUnet allows updates
-to certain content to be made available. This section is supposed
-to introduce users to the concepts that are used to achive these goals.
-
-
-@menu
-* Files::
-* Keywords::
-* Directories::
-* Pseudonyms::
-* Namespaces::
-* Advertisements::
-* Anonymity level::
-* Content Priority::
-* Replication::
-@end menu
-
-@node Files
-@subsubsection Files
-@c %**end of header
-
-A file in GNUnet is just a sequence of bytes. Any file-format is allowed
-and the maximum file size is theoretically 264 bytes, except that it
-would take an impractical amount of time to share such a file.
-GNUnet itself never interprets the contents of shared files, except
-when using GNU libextractor to obtain keywords.
-
-@node Keywords
-@subsubsection Keywords
-@c %**end of header
-
-Keywords are the most simple mechanism to find files on GNUnet.
-Keywords are @strong{case-sensitive} and the search string
-must always match @strong{exactly} the keyword used by the
-person providing the file. Keywords are never transmitted in
-plaintext. The only way for an adversary to determine the keyword
-that you used to search is to guess it (which then allows the
-adversary to produce the same search request). Since providing
-keywords by hand for each shared file is tedious, GNUnet uses
-GNU libextractor to help automate this process. Starting a
-keyword search on a slow machine can take a little while since
-the keyword search involves computing a fresh RSA key to formulate the
-request.
-
-@node Directories
-@subsubsection Directories
-@c %**end of header
-
-A directory in GNUnet is a list of file identifiers with meta data.
-The file identifiers provide sufficient information about the files
-to allow downloading the contents. Once a directory has been created,
-it cannot be changed since it is treated just like an ordinary file
-by the network. Small files (of a few kilobytes) can be inlined in
-the directory, so that a separate download becomes unnecessary.
-
-@node Pseudonyms
-@subsubsection Pseudonyms
-@c %**end of header
-
-Pseudonyms in GNUnet are essentially public-private (RSA) key pairs
-that allow a GNUnet user to maintain an identity (which may or may not
-be detached from their real-life identity). GNUnet's pseudonyms are not
-file-sharing specific --- and they will likely be used by many GNUnet
-applications where a user identity is required.
-
-Note that a pseudonym is NOT bound to a GNUnet peer. There can be multiple
-pseudonyms for a single user, and users could (theoretically) share the
-private pseudonym keys (currently only out-of-band by knowing which files
-to copy around).
-
-@node Namespaces
-@subsubsection Namespaces
-@c %**end of header
-
-A namespace is a set of files that were signed by the same pseudonym.
-Files (or directories) that have been signed and placed into a namespace
-can be updated. Updates are identified as authentic if the same secret
-key was used to sign the update. Namespaces are also useful to establish
-a reputation, since all of the content in the namespace comes from the
-same entity (which does not have to be the same person).
-
-@node Advertisements
-@subsubsection Advertisements
-@c %**end of header
-
-Advertisements are used to notify other users about the existence of a
-namespace. Advertisements are propagated using the normal keyword search.
-When an advertisement is received (in response to a search), the namespace
-is added to the list of namespaces available in the namespace-search
-dialogs of gnunet-fs-gtk and printed by gnunet-pseudonym. Whenever a
-namespace is created, an appropriate advertisement can be generated.
-The default keyword for the advertising of namespaces is "namespace".
-
-Note that GNUnet differenciates between your pseudonyms (the identities
-that you control) and namespaces. If you create a pseudonym, you will
-not automatically see the respective namespace. You first have to create
-an advertisement for the namespace and find it using keyword
-search --- even for your own namespaces. The @code{gnunet-pseudonym}
-tool is currently responsible for both managing pseudonyms and namespaces.
-This will likely change in the future to reduce the potential for
-confusion.
-
-@node Anonymity level
-@subsubsection Anonymity level
-@c %**end of header
-
-The anonymity level determines how hard it should be for an adversary to
-determine the identity of the publisher or the searcher/downloader. An
-anonymity level of zero means that anonymity is not required. The default
-anonymity level of "1" means that anonymous routing is desired, but no
-particular amount of cover traffic is necessary. A powerful adversary
-might thus still be able to deduce the origin of the traffic using
-traffic analysis. Specifying higher anonymity levels increases the
-amount of cover traffic required. While this offers better privacy,
-it can also significantly hurt performance.
-
-@node Content Priority
-@subsubsection Content Priority
-@c %**end of header
-
-Depending on the peer's configuration, GNUnet peers migrate content
-between peers. Content in this sense are individual blocks of a file,
-not necessarily entire files. When peers run out of space (due to
-local publishing operations or due to migration of content from other
-peers), blocks sometimes need to be discarded. GNUnet first always
-discards expired blocks (typically, blocks are published with an
-expiration of about two years in the future; this is another option).
-If there is still not enough space, GNUnet discards the blocks with the
-lowest priority. The priority of a block is decided by its popularity
-(in terms of requests from peers we trust) and, in case of blocks
-published locally, the base-priority that was specified by the user
-when the block was published initially.
-
-@node Replication
-@subsubsection Replication
-@c %**end of header
-
-When peers migrate content to other systems, the replication level
-of a block is used to decide which blocks need to be migrated most
-urgently. GNUnet will always push the block with the highest
-replication level into the network, and then decrement the replication
-level by one. If all blocks reach replication level zero, the
-selection is simply random.
-
-@node File-sharing Publishing
-@subsection File-sharing Publishing
-@c %**end of header
-
-The command @code{gnunet-publish} can be used to add content
-to the network. The basic format of the command is
-
-@example
-$ gnunet-publish [-n] [-k KEYWORDS]* [-m TYPE:VALUE] FILENAME
-@end example
-
-
-@menu
-* Important command-line options::
-* Indexing vs. Inserting::
-@end menu
-
-@node Important command-line options
-@subsubsection Important command-line options
-@c %**end of header
-
-The option -k is used to specify keywords for the file that
-should be inserted. You can supply any number of keywords,
-and each of the keywords will be sufficient to locate and
-retrieve the file.
-
-The -m option is used to specify meta-data, such as descriptions.
-You can use -m multiple times. The TYPE passed must be from the
-list of meta-data types known to libextractor. You can obtain this
-list by running @code{extract -L}. Use quotes around the entire
-meta-data argument if the value contains spaces. The meta-data
-is displayed to other users when they select which files to
-download. The meta-data and the keywords are optional and
-maybe inferred using @code{GNU libextractor}.
-
-gnunet-publish has a few additional options to handle namespaces and
-directories. See the man-page for details.
-
-@node Indexing vs. Inserting
-@subsubsection Indexing vs Inserting
-@c %**end of header
-
-By default, GNUnet indexes a file instead of making a full copy.
-This is much more efficient, but requries the file to stay unaltered
-at the location where it was when it was indexed. If you intend to move,
-delete or alter a file, consider using the option @code{-n} which will
-force GNUnet to make a copy of the file in the database.
-
-Since it is much less efficient, this is strongly discouraged for large
-files. When GNUnet indexes a file (default), GNUnet does @strong{not}
-create an additional encrypted copy of the file but just computes a
-summary (or index) of the file. That summary is approximately two percent
-of the size of the original file and is stored in GNUnet's database.
-Whenever a request for a part of an indexed file reaches GNUnet,
-this part is encrypted on-demand and send out. This way, there is no
-need for an additional encrypted copy of the file to stay anywhere
-on the drive. This is different from other systems, such as Freenet,
-where each file that is put online must be in Freenet's database in
-encrypted format, doubling the space requirements if the user wants
-to preseve a directly accessible copy in plaintext.
-
-Thus indexing should be used for all files where the user will keep
-using this file (at the location given to gnunet-publish) and does
-not want to retrieve it back from GNUnet each time. If you want to
-remove a file that you have indexed from the local peer, use the tool
-@code{gnunet-unindex} to un-index the file.
-
-The option @code{-n} may be used if the user fears that the file might
-be found on their drive (assuming the computer comes under the control
-of an adversary). When used with the @code{-n} flag, the user has a
-much better chance of denying knowledge of the existence of the file,
-even if it is still (encrypted) on the drive and the adversary is
-able to crack the encryption (e.g. by guessing the keyword.
-
-@node File-sharing Searching
-@subsection File-sharing Searching
-@c %**end of header
-
-The command @code{gnunet-search} can be used to search
-for content on GNUnet. The format is:
-
-@example
-$ gnunet-search [-t TIMEOUT] KEYWORD
-@end example
-
-@noindent
-The -t option specifies that the query should timeout after
-approximately TIMEOUT seconds. A value of zero is interpreted
-as @emph{no timeout}, which is also the default. In this case,
-gnunet-search will never terminate (unless you press CTRL-C).
-
-If multiple words are passed as keywords, they will all be
-considered optional. Prefix keywords with a "+" to make them mandatory.
-
-Note that searching using
-
-@example
-$ gnunet-search Das Kapital
-@end example
-
-@noindent
-is not the same as searching for
-
-@example
-$ gnunet-search "Das Kapital"
-@end example
-
-@noindent
-as the first will match files shared under the keywords
-"Das" or "Kapital" whereas the second will match files
-shared under the keyword "Das Kapital".
-
-Search results are printed by gnunet-search like this:
-
-@example
-$ gnunet-download -o "COPYING" --- gnunet://fs/chk/N8...C92.17992
-=> The GNU Public License <= (mimetype: text/plain)
-@end example
-
-@noindent
-The first line is the command you would have to enter to download
-the file. The argument passed to @code{-o} is the suggested
-filename (you may change it to whatever you like).
-The @code{--} is followed by key for decrypting the file,
-the query for searching the file, a checksum (in hexadecimal)
-finally the size of the file in bytes.
-The second line contains the description of the file; here this is
-"The GNU Public License" and the mime-type (see the options for
-gnunet-publish on how to specify these).
-
-@node File-sharing Downloading
-@subsection File-sharing Downloading
-@c %**end of header
-
-In order to download a file, you need the three values returned by
-@code{gnunet-search}.
-You can then use the tool @code{gnunet-download} to obtain the file:
-
-@example
-$ gnunet-download -o FILENAME --- GNUNETURL
-@end example
-
-@noindent
-FILENAME specifies the name of the file where GNUnet is supposed
-to write the result. Existing files are overwritten. If the
-existing file contains blocks that are identical to the
-desired download, those blocks will not be downloaded again
-(automatic resume).
-
-If you want to download the GPL from the previous example,
-you do the following:
-
-@example
-$ gnunet-download -o "COPYING" --- gnunet://fs/chk/N8...92.17992
-@end example
-
-@noindent
-If you ever have to abort a download, you can continue it at any time by
-re-issuing @command{gnunet-download} with the same filename.
-In that case, GNUnet will @strong{not} download blocks again that are
-already present.
-
-GNUnet's file-encoding mechanism will ensure file integrity, even if the
-existing file was not downloaded from GNUnet in the first place.
-
-You may want to use the @command{-V} switch (must be added before
-the @command{--}) to turn on verbose reporting. In this case,
-@command{gnunet-download} will print the current number of
-bytes downloaded whenever new data was received.
-
-@node File-sharing Directories
-@subsection File-sharing Directories
-@c %**end of header
-
-Directories are shared just like ordinary files. If you download a
-directory with @command{gnunet-download}, you can use
-@command{gnunet-directory} to list its contents. The canonical
-extension for GNUnet directories when stored as files in your
-local file-system is ".gnd". The contents of a directory are URIs and
-meta data.
-The URIs contain all the information required by
-@command{gnunet-download} to retrieve the file. The meta data
-typically includes the mime-type, description, a filename and
-other meta information, and possibly even the full original file
-(if it was small).
-
-@node File-sharing Namespace Management
-@subsection File-sharing Namespace Management
-@c %**end of header
-
-@b{Please note that the text in this subsection is outdated and needs}
-@b{to be rewritten for version 0.10!}
-
-The gnunet-pseudonym tool can be used to create pseudonyms and
-to advertise namespaces. By default, gnunet-pseudonym simply
-lists all locally available pseudonyms.
-
-
-@menu
-* Creating Pseudonyms::
-* Deleting Pseudonyms::
-* Advertising namespaces::
-* Namespace names::
-* Namespace root::
-@end menu
-
-@node Creating Pseudonyms
-@subsubsection Creating Pseudonyms
-@c %**end of header
-
-With the @command{-C NICK} option it can also be used to
-create a new pseudonym. A pseudonym is the virtual identity
-of the entity in control of a namespace. Anyone can create
-any number of pseudonyms. Note that creating a pseudonym can
-take a few minutes depending on the performance of the machine
-used.
-
-@node Deleting Pseudonyms
-@subsubsection Deleting Pseudonyms
-@c %**end of header
-
-With the @command{-D NICK} option pseudonyms can be deleted.
-Once the pseudonym has been deleted it is impossible to add
-content to the corresponding namespace. Deleting the
-pseudonym does not make the namespace or any content in it
-unavailable.
-
-@node Advertising namespaces
-@subsubsection Advertising namespaces
-@c %**end of header
-
-Each namespace is associated with meta-data that describes
-the namespace. This meta data is provided by the user at
-the time that the namespace is advertised. Advertisements
-are published under keywords so that they can be found using
-normal keyword-searches. This way, users can learn about new
-namespaces without relying on out-of-band communication or directories.
-A suggested keyword to use for all namespaces is simply "namespace".
-When a keyword-search finds a namespace advertisement,
-it is automatically stored in a local list of known namespaces.
-Users can then associate a rank with the namespace to remember
-the quality of the content found in it.
-
-@node Namespace names
-@subsubsection Namespace names
-@c %**end of header
-
-While the namespace is uniquely identified by its ID, another way
-to refer to the namespace is to use the NICKNAME.
-The NICKNAME can be freely chosen by the creator of the namespace and
-hence conflicts are possible. If a GNUnet client learns about more
-than one namespace using the same NICKNAME, the ID is appended
-to the NICKNAME to get a unique identifier.
-
-@node Namespace root
-@subsubsection Namespace root
-@c %**end of header
-
-An item of particular interest in the namespace advertisement is
-the ROOT. The ROOT is the identifier of a designated entry in the
-namespace. The idea is that the ROOT can be used to advertise an
-entry point to the content of the namespace.
-
-@node File-Sharing URIs
-@subsection File-Sharing URIs
-@c %**end of header
-
-GNUnet (currently) uses four different types of URIs for
-file-sharing. They all begin with "gnunet://fs/".
-This section describes the four different URI types in detail.
-
-
-@menu
-* Encoding of hash values in URIs::
-* Content Hash Key (chk)::
-* Location identifiers (loc)::
-* Keyword queries (ksk)::
-* Namespace content (sks)::
-@end menu
-
-@node Encoding of hash values in URIs
-@subsubsection Encoding of hash values in URIs
-@c %**end of header
-
-Most URIs include some hash values. Hashes are encoded using
-base32hex (RFC 2938).
-
-@node Content Hash Key (chk)
-@subsubsection Content Hash Key (chk)
-@c %**end of header
-
-A chk-URI is used to (uniquely) identify a file or directory
-and to allow peers to download the file. Files are stored in
-GNUnet as a tree of encrypted blocks.
-The chk-URI thus contains the information to download and decrypt
-those blocks. A chk-URI has the format
-"gnunet://fs/chk/KEYHASH.QUERYHASH.SIZE". Here, "SIZE"
-is the size of the file (which allows a peer to determine the
-shape of the tree), KEYHASH is the key used to decrypt the file
-(also the hash of the plaintext of the top block) and QUERYHASH
-is the query used to request the top-level block (also the hash
-of the encrypted block).
-
-@node Location identifiers (loc)
-@subsubsection Location identifiers (loc)
-@c %**end of header
-
-For non-anonymous file-sharing, loc-URIs are used to specify which
-peer is offering the data (in addition to specifying all of the
-data from a chk-URI). Location identifiers include a digital
-signature of the peer to affirm that the peer is truly the
-origin of the data. The format is
-"gnunet://fs/loc/KEYHASH.QUERYHASH.SIZE.PEER.SIG.EXPTIME".
-Here, "PEER" is the public key of the peer (in GNUnet format in
-base32hex), SIG is the RSA signature (in GNUnet format in
-base32hex) and EXPTIME specifies when the signature expires
-(in milliseconds after 1970).
-
-@node Keyword queries (ksk)
-@subsubsection Keyword queries (ksk)
-@c %**end of header
-
-A keyword-URI is used to specify that the desired operation
-is the search using a particular keyword. The format is simply
-"gnunet://fs/ksk/KEYWORD". Non-ASCII characters can be specified
-using the typical URI-encoding (using hex values) from HTTP.
-"+" can be used to specify multiple keywords (which are then
-logically "OR"-ed in the search, results matching both keywords
-are given a higher rank): "gnunet://fs/ksk/KEYWORD1+KEYWORD2".
-
-@node Namespace content (sks)
-@subsubsection Namespace content (sks)
-@c %**end of header
-
-Namespaces are sets of files that have been approved by some (usually
-pseudonymous) user --- typically by that user publishing all of the
-files together. A file can be in many namespaces. A file is in a
-namespace if the owner of the ego (aka the namespace's private key)
-signs the CHK of the file cryptographically. An SKS-URI is used to
-search a namespace. The result is a block containing meta data,
-the CHK and the namespace owner's signature. The format of a sks-URI
-is "gnunet://fs/sks/NAMESPACE/IDENTIFIER". Here, "NAMESPACE"
-is the public key for the namespace. "IDENTIFIER" is a freely
-chosen keyword (or password!). A commonly used identifier is
-"root" which by convention refers to some kind of index or other
-entry point into the namespace.
-
-@node The GNU Name System
-@section The GNU Name System
-@c %**end of header
-
-
-The GNU Name System (GNS) is secure and decentralized naming system.
-It allows its users to resolve and register names within the @code{.gnu}
-@dfn{top-level domain} (TLD).
-
-GNS is designed to provide:
-@itemize @bullet
-@item Censorship resistance
-@item Query privacy
-@item Secure name resolution
-@item Compatibility with DNS
-@end itemize
-
-For the initial configuration and population of your
-GNS installation, please follow the GNS setup instructions.
-The remainder of this chapter will provide some background on GNS
-and then describe how to use GNS in more detail.
-
-Unlike DNS, GNS does not rely on central root zones or authorities.
-Instead any user administers their own root and can can create arbitrary
-name value mappings. Furthermore users can delegate resolution to other
-users' zones just like DNS NS records do. Zones are uniquely identified
-via public keys and resource records are signed using the corresponding
-public key. Delegation to another user's zone is done using special PKEY
-records and petnames. A petname is a name that can be freely chosen by
-the user. This results in non-unique name-value mappings as
-@code{@uref{http://www.bob.gnu/, www.bob.gnu}} to one user might be
-@code{@uref{http://www.friend.gnu/, www.friend.gnu}} for someone else.
-
-
-@menu
-* Maintaining your own Zones::
-* Obtaining your Zone Key::
-* Adding Links to Other Zones::
-* The Three Local Zones of GNS::
-* The Master Zone::
-* The Private Zone::
-* The Shorten Zone::
-* The ZKEY Top Level Domain in GNS::
-* Resource Records in GNS::
-@end menu
-
-
-@node Maintaining your own Zones
-@subsection Maintaining your own Zones
-
-To setup your GNS system you must execute:
-
-@example
-$ gnunet-gns-import.sh
-@end example
-
-@noindent
-This will boostrap your zones and create the necessary key material.
-Your keys can be listed using the @command{gnunet-identity}
-command line tool:
-
-@example
-$ gnunet-identity -d
-@end example
-
-@noindent
-You can arbitrarily create your own zones using the gnunet-identity
-tool using:
-
-@example
-$ gnunet-identity -C "new_zone"
-@end example
-
-@noindent
-Now you can add (or edit, or remove) records in your GNS zone using the
-gnunet-setup GUI or using the gnunet-namestore command-line tool.
-In either case, your records will be stored in an SQL database under
-control of the gnunet-service-namestore. Note that if multiple users
-use one peer, the namestore database will include the combined records
-of all users. However, users will not be able to see each other's records
-if they are marked as private.
-
-To provide a simple example for editing your own zone, suppose you
-have your own web server with IP 1.2.3.4. Then you can put an
-A record (A records in DNS are for IPv4 IP addresses) into your
-local zone using the command:
-
-@example
-$ gnunet-namestore -z master-zone -a -n www -t A -V 1.2.3.4 -e never
-@end example
-
-@noindent
-Afterwards, you will be able to access your webpage under "www.gnu"
-(assuming your webserver does not use virtual hosting, if it does,
-please read up on setting up the GNS proxy).
-
-Similar commands will work for other types of DNS and GNS records,
-the syntax largely depending on the type of the record.
-Naturally, most users may find editing the zones using the
-@command{gnunet-setup} GUI to be easier.
-
-@node Obtaining your Zone Key
-@subsection Obtaining your Zone Key
-
-Each zone in GNS has a public-private key. Usually, gnunet-namestore and
-gnunet-setup will access your private key as necessary, so you do not
-have to worry about those. What is important is your public key
-(or rather, the hash of your public key), as you will likely want to
-give it to others so that they can securely link to you.
-
-You can usually get the hash of your public key using
-
-@example
-$ gnunet-identity -d $options | grep master-zone | awk '@{print $3@}'
-@end example
-
-@noindent
-For example, the output might be something like:
-
-@example
-DC3SEECJORPHQNVRH965A6N74B1M37S721IG4RBQ15PJLLPJKUE0
-@end example
-
-@noindent
-Alternatively, you can obtain a QR code with your zone key AND
-your pseudonym from gnunet-gtk. The QR code is displayed in the
-GNS tab and can be stored to disk using the Save as button next
-to the image.
-
-@node Adding Links to Other Zones
-@subsection Adding Links to Other Zones
-
-
-A central operation in GNS is the ability to securely delegate to
-other zones. Basically, by adding a delegation you make all of the
-names from the other zone available to yourself. This section
-describes how to create delegations.
-
-Suppose you have a friend who you call 'bob' who also uses GNS.
-You can then delegate resolution of names to Bob's zone by adding
-a PKEY record to their local zone:
-
-@example
-$ gnunet-namestore -a -n bob --type PKEY -V XXXX -e never
-@end example
-
-@noindent
-Note that XXXX in the command above must be replaced with the
-hash of Bob's public key (the output your friend obtained using
-the gnunet-identity command from the previous section and told you,
-for example by giving you a business card containing this
-information as a QR code).
-
-Assuming Bob has an A record for their website under the name of
-www in his zone, you can then access Bob's website under
-www.bob.gnu --- as well as any (public) GNS record that Bob has
-in their zone by replacing www with the respective name of the
-record in Bob's zone.
-
-@c themselves? themself?
-Furthermore, if Bob has themselves a (public) delegation to Carol's
-zone under "carol", you can access Carol's records under
-NAME.carol.bob.gnu (where NAME is the name of Carol's record you
-want to access).
-
-@node The Three Local Zones of GNS
-@subsection The Three Local Zones of GNS
-
-Each user GNS has control over three zones. Each of the zones
-has a different purpose. These zones are the
-
-@itemize @bullet
-
-@item master zone,
-@item private zone, and the
-@item shorten zone.
-@end itemize
-
-@node The Master Zone
-@subsection The Master Zone
-
-
-The master zone is your personal TLD. Names within the @code{.gnu}
-namespace are resolved relative to this zone. You can arbitrarily
-add records to this zone and selectively publish those records.
-
-@node The Private Zone
-@subsection The Private Zone
-
-
-The private zone is a subzone (or subdomain in DNS terms) of your
-master zone. It should be used for records that you want to keep
-private. For example @code{bank.private.gnu}. The key idea is that
-you want to keep your private records separate, if just to know
-that those names are not available to other users.
-
-@node The Shorten Zone
-@subsection The Shorten Zone
-
-
-The shorten zone can either be a subzone of the master zone or the
-private zone. It is different from the other zones in that GNS
-will automatically populate this zone with other users' zones based
-on their PSEU records whenever you resolve a name.
-
-For example if you go to
-@code{@uref{http://www.bob.alice.dave.gnu/, www.bob.alice.dave.gnu}},
-GNS will try to import @code{bob} into your shorten zone. Having
-obtained Bob's PKEY from @code{alice.dave.gnu}, GNS will lookup the
-PSEU record for @code{+} in Bob's zone. If it exists and the specified
-pseudonym is not taken, Bob's PKEY will be automatically added under
-that pseudonym (i.e. "bob") into your shorten zone. From then on,
-Bob's webpage will also be available for you as
-@code{@uref{http://www.bob.short.gnu/, www.bob.short.gnu}}.
-This feature is called @b{automatic name shortening} and is supposed to
-keep GNS names as short and memorable as possible.
-
-@node The ZKEY Top Level Domain in GNS
-@subsection The ZKEY Top Level Domain in GNS
-
-
-GNS also provides a secure and globally unique namespace under the .zkey
-top-level domain. A name in the .zkey TLD corresponds to the (printable)
-public key of a zone. Names in the .zkey TLD are then resolved by querying
-the respective zone. The .zkey TLD is expected to be used under rare
-circumstances where globally unique names are required and for
-integration with legacy systems.
-
-@node Resource Records in GNS
-@subsection Resource Records in GNS
-
-
-GNS supports the majority of the DNS records as defined in
-@uref{http://www.ietf.org/rfc/rfc1035.txt, RFC 1035}. Additionally,
-GNS defines some new record types the are unique to the GNS system.
-For example, GNS-specific resource records are used to give petnames
-for zone delegation, revoke zone keys and provide some compatibility
-features.
-
-For some DNS records, GNS does extended processing to increase their
-usefulness in GNS. In particular, GNS introduces special names
-referred to as "zone relative names". Zone relative names are allowed
-in some resource record types (for example, in NS and CNAME records)
-and can also be used in links on webpages. Zone relative names end
-in ".+" which indicates that the name needs to be resolved relative
-to the current authoritative zone. The extended processing of those
-names will expand the ".+" with the correct delegation chain to the
-authoritative zone (replacing ".+" with the name of the location
-where the name was encountered) and hence generate a
-valid @code{.gnu} name.
-
-GNS currently supports the following record types:
-
-@menu
-* NICK::
-* PKEY::
-* BOX::
-* LEHO::
-* VPN::
-* A AAAA and TXT::
-* CNAME::
-* GNS2DNS::
-* SOA SRV PTR and MX::
-@end menu
-
-@node NICK
-@subsubsection NICK
-
-A NICK record is used to give a zone a name. With a NICK record, you can
-essentially specify how you would like to be called. GNS expects this
-record under the name "+" in the zone's database (NAMESTORE); however,
-it will then automatically be copied into each record set, so that
-clients never need to do a separate lookup to discover the NICK record.
-
-@b{Example}@
-
-@example
-Name: +; RRType: NICK; Value: bob
-@end example
-
-@noindent
-This record in Bob's zone will tell other users that this zone wants
-to be referred to as 'bob'. Note that nobody is obliged to call Bob's
-zone 'bob' in their own zones. It can be seen as a
-recommendation ("Please call me 'bob'").
-
-@node PKEY
-@subsubsection PKEY
-
-PKEY records are used to add delegation to other users' zones and
-give those zones a petname.
-
-@b{Example}@
-
-Let Bob's zone be identified by the hash "ABC012". Bob is your friend
-so you want to give them the petname "friend". Then you add the
-following record to your zone:
-
-@example
-Name: friend; RRType: PKEY; Value: ABC012;
-@end example
-
-@noindent
-This will allow you to resolve records in bob's zone
-under "*.friend.gnu".
-
-@node BOX
-@subsubsection BOX
-
-BOX records are there to integrate information from TLSA or
-SRV records under the main label. In DNS, TLSA and SRV records
-use special names of the form @code{_port._proto.(label.)*tld} to
-indicate the port number and protocol (i.e. tcp or udp) for which
-the TLSA or SRV record is valid. This causes various problems, and
-is elegantly solved in GNS by integrating the protocol and port
-numbers together with the respective value into a "BOX" record.
-Note that in the GUI, you do not get to edit BOX records directly
-right now --- the GUI will provide the illusion of directly
-editing the TLSA and SRV records, even though they internally
-are BOXed up.
-
-@node LEHO
-@subsubsection LEHO
-
-The LEgacy HOstname of a server. Some webservers expect a specific
-hostname to provide a service (virtiual hosting). Also SSL
-certificates usually contain DNS names. To provide the expected
-legacy DNS name for a server, the LEHO record can be used.
-To mitigate the just mentioned issues the GNS proxy has to be used.
-The GNS proxy will use the LEHO information to apply the necessary
-transformations.
-
-@node VPN
-@subsubsection VPN
-
-GNS allows easy access to services provided by the GNUnet Virtual Public
-Network. When the GNS resolver encounters a VPN record it will contact
-the VPN service to try and allocate an IPv4/v6 address (if the queries
-record type is an IP address) that can be used to contact the service.
-
-@b{Example}@
-
-I want to provide access to the VPN service "web.gnu." on port 80 on peer
-ABC012:@
-Name: www; RRType: VPN; Value: 80 ABC012 web.gnu.
-
-The peer ABC012 is configured to provide an exit point for the service
-"web.gnu." on port 80 to it's server running locally on port 8080 by
-having the following lines in the @file{gnunet.conf} configuration file:
-
-@example
-[web.gnunet.]
-TCP_REDIRECTS = 80:localhost4:8080
-@end example
-
-@node A AAAA and TXT
-@subsubsection A AAAA and TXT
-
-Those records work in exactly the same fashion as in traditional DNS.
-
-@node CNAME
-@subsubsection CNAME
-
-As specified in RFC 1035 whenever a CNAME is encountered the query
-needs to be restarted with the specified name. In GNS a CNAME
-can either be:
-
-@itemize @bullet
-@item A zone relative name,
-@item A zkey name or
-@item A DNS name (in which case resolution will continue outside
-of GNS with the systems DNS resolver)
-@end itemize
-
-@node GNS2DNS
-@subsubsection GNS2DNS
-
-GNS can delegate authority to a legacy DNS zone. For this, the
-name of the DNS nameserver and the name of the DNS zone are
-specified in a GNS2DNS record.
-
-@b{Example}
-
-@example
-Name: pet; RRType: GNS2DNS; Value: gnunet.org@@a.ns.joker.com
-@end example
-
-@noindent
-Any query to @code{pet.gnu} will then be delegated to the DNS server at
-@code{a.ns.joker.com}. For example,
-@code{@uref{http://www.pet.gnu/, www.pet.gnu}} will result in a DNS query
-for @code{@uref{http://www.gnunet.org/, www.gnunet.org}} to the server
-at @code{a.ns.joker.com}. Delegation to DNS via NS records in GNS can
-be useful if you do not want to start resolution in the DNS root zone
-(due to issues such as censorship or availability).
-
-Note that you would typically want to use a relative name for the
-nameserver, i.e.
-
-@example
-Name: pet; RRType: GNS2DNS; Value: gnunet.org@@ns-joker.+@
-Name: ns-joker; RRType: A; Value: 184.172.157.218
-@end example
-
-@noindent
-This way, you can avoid involving the DNS hierarchy in the resolution of
-@code{a.ns.joker.com}. In the example above, the problem may not be
-obvious as the nameserver for "gnunet.org" is in the ".com" zone.
-However, imagine the nameserver was "ns.gnunet.org". In this case,
-delegating to "ns.gnunet.org" would mean that despite using GNS,
-censorship in the DNS ".org" zone would still be effective.
-
-@node SOA SRV PTR and MX
-@subsubsection SOA SRV PTR and MX
-
-The domain names in those records can, again, be either
-
-@itemize @bullet
-@item A zone relative name,
-@item A zkey name or
-@item A DNS name
-@end itemize
-
-The resolver will expand the zone relative name if possible.
-Note that when using MX records within GNS, the target mail
-server might still refuse to accept e-mails to the resulting
-domain as the name might not match. GNS-enabled mail clients
-should use the ZKEY zone as the destination hostname and
-GNS-enabled mail servers should be configured to accept
-e-mails to the ZKEY-zones of all local users.
-
-@node Using the Virtual Public Network
-@section Using the Virtual Public Network
-
-@menu
-* Setting up an Exit node::
-* Fedora and the Firewall::
-* Setting up VPN node for protocol translation and tunneling::
-@end menu
-
-Using the GNUnet Virtual Public Network (VPN) application you can
-tunnel IP traffic over GNUnet. Moreover, the VPN comes
-with built-in protocol translation and DNS-ALG support, enabling
-IPv4-to-IPv6 protocol translation (in both directions).
-This chapter documents how to use the GNUnet VPN.
-
-The first thing to note about the GNUnet VPN is that it is a public
-network. All participating peers can participate and there is no
-secret key to control access. So unlike common virtual private
-networks, the GNUnet VPN is not useful as a means to provide a
-"private" network abstraction over the Internet. The GNUnet VPN
-is a virtual network in the sense that it is an overlay over the
-Internet, using its own routing mechanisms and can also use an
-internal addressing scheme. The GNUnet VPN is an Internet
-underlay --- TCP/IP applications run on top of it.
-
-The VPN is currently only supported on GNU/Linux systems.
-Support for operating systems that support TUN (such as FreeBSD)
-should be easy to add (or might not even require any coding at
-all --- we just did not test this so far). Support for other
-operating systems would require re-writing the code to create virtual
-network interfaces and to intercept DNS requests.
-
-The VPN does not provide good anonymity. While requests are routed
-over the GNUnet network, other peers can directly see the source
-and destination of each (encapsulated) IP packet. Finally, if you
-use the VPN to access Internet services, the peer sending the
-request to the Internet will be able to observe and even alter
-the IP traffic. We will discuss additional security implications
-of using the VPN later in this chapter.
-
-@node Setting up an Exit node
-@subsection Setting up an Exit node
-
-Any useful operation with the VPN requires the existence of an exit
-node in the GNUnet Peer-to-Peer network. Exit functionality can only
-be enabled on peers that have regular Internet access. If you want
-to play around with the VPN or support the network, we encourage
-you to setup exit nodes. This chapter documents how to setup an
-exit node.
-
-There are four types of exit functions an exit node can provide,
-and using the GNUnet VPN to access the Internet will only work
-nicely if the first three types are provided somewhere in
-the network. The four exit functions are:
-
-@itemize @bullet
-@item DNS: allow other peers to use your DNS resolver
-@item IPv4: allow other peers to access your IPv4 Internet connection
-@item IPv6: allow other peers to access your IPv6 Internet connection
-@item Local service: allow other peers to access a specific TCP or
-UDP service your peer is providing
-@end itemize
-
-By enabling "exit" in gnunet-setup and checking the respective boxes
-in the "exit" tab, you can easily choose which of the above exit
-functions you want to support.
-
-Note, however, that by supporting the first three functions you will
-allow arbitrary other GNUnet users to access the Internet via your
-system. This is somewhat similar to running a Tor exit node. The
-Torproject has a nice article about what to consider if you want
-to do this here. We believe that generally running a DNS exit node
-is completely harmless.
-
-The exit node configuration does currently not allow you to restrict the
-Internet traffic that leaves your system. In particular, you cannot
-exclude SMTP traffic (or block port 25) or limit to HTTP traffic using
-the GNUnet configuration. However, you can use your host firewall to
-restrict outbound connections from the virtual tunnel interface. This
-is highly recommended. In the future, we plan to offer a wider range
-of configuration options for exit nodes.
-
-Note that by running an exit node GNUnet will configure your kernel
-to perform IP-forwarding (for IPv6) and NAT (for IPv4) so that the
-traffic from the virtual interface can be routed to the Internet.
-In order to provide an IPv6-exit, you need to have a subnet routed
-to your host's external network interface and assign a subrange of
-that subnet to the GNUnet exit's TUN interface.
-
-When running a local service, you should make sure that the local
-service is (also) bound to the IP address of your EXIT interface
-(i.e. 169.254.86.1). It will NOT work if your local service is
-just bound to loopback. You may also want to create a "VPN" record
-in your zone of the GNU Name System to make it easy for others to
-access your service via a name instead of just the full service
-descriptor. Note that the identifier you assign the service can
-serve as a passphrase or shared secret, clients connecting to the
-service must somehow learn the service's name. VPN records in the
-GNU Name System can make this easier.
-
-@node Fedora and the Firewall
-@subsection Fedora and the Firewall
-
-
-When using an exit node on Fedora 15, the standard firewall can
-create trouble even when not really exiting the local system!
-For IPv4, the standard rules seem fine. However, for IPv6 the
-standard rules prohibit traffic from the network range of the
-virtual interface created by the exit daemon to the local IPv6
-address of the same interface (which is essentially loopback
-traffic, so you might suspect that a standard firewall would
-leave this traffic alone). However, as somehow for IPv6 the
-traffic is not recognized as originating from the local
-system (and as the connection is not already "established"),
-the firewall drops the traffic. You should still get ICMPv6
-packets back, but that's obviously not very useful.
-
-Possible ways to fix this include disabling the firewall (do you
-have a good reason for having it on?) or disabling the firewall
-at least for the GNUnet exit interface (or the respective
-IPv4/IPv6 address range). The best way to diagnose these kinds
-of problems in general involves setting the firewall to REJECT
-instead of DROP and to watch the traffic using wireshark
-(or tcpdump) to see if ICMP messages are generated when running
-some tests that should work.
-
-@node Setting up VPN node for protocol translation and tunneling
-@subsection Setting up VPN node for protocol translation and tunneling
-
-
-The GNUnet VPN/PT subsystem enables you to tunnel IP traffic over the
-VPN to an exit node, from where it can then be forwarded to the
-Internet. This section documents how to setup VPN/PT on a node.
-Note that you can enable both the VPN and an exit on the same peer.
-In this case, IP traffic from your system may enter your peer's VPN
-and leave your peer's exit. This can be useful as a means to do
-protocol translation. For example, you might have an application that
-supports only IPv4 but needs to access an IPv6-only site. In this case,
-GNUnet would perform 4to6 protocol translation between the VPN (IPv4)
-and the Exit (IPv6). Similarly, 6to4 protocol translation is also
-possible. However, the primary use for GNUnet would be to access
-an Internet service running with an IP version that is not supported
-by your ISP. In this case, your IP traffic would be routed via GNUnet
-to a peer that has access to the Internet with the desired IP version.
-
-Setting up an entry node into the GNUnet VPN primarily requires you
-to enable the "VPN/PT" option in "gnunet-setup". This will launch the
-"gnunet-service-vpn", "gnunet-service-dns" and "gnunet-daemon-pt"
-processes. The "gnunet-service-vpn" will create a virtual interface
-which will be used as the target for your IP traffic that enters the
-VPN. Additionally, a second virtual interface will be created by
-the "gnunet-service-dns" for your DNS traffic. You will then need to
-specify which traffic you want to tunnel over GNUnet. If your ISP only
-provides you with IPv4 or IPv6-access, you may choose to tunnel the
-other IP protocol over the GNUnet VPN. If you do not have an ISP
-(and are connected to other GNUnet peers via WLAN), you can also
-choose to tunnel all IP traffic over GNUnet. This might also provide
-you with some anonymity. After you enable the respective options
-and restart your peer, your Internet traffic should be tunneled
-over the GNUnet VPN.
-
-The GNUnet VPN uses DNS-ALG to hijack your IP traffic. Whenever an
-application resolves a hostname (i.e. 'gnunet.org'), the
-"gnunet-daemon-pt" will instruct the "gnunet-service-dns" to intercept
-the request (possibly route it over GNUnet as well) and replace the
-normal answer with an IP in the range of the VPN's interface.
-"gnunet-daemon-pt" will then tell "gnunet-service-vpn" to forward all
-traffic it receives on the TUN interface via the VPN to the original
-destination.
-
-For applications that do not use DNS, you can also manually create
-such a mapping using the gnunet-vpn command-line tool. Here, you
-specfiy the desired address family of the result (i.e. "-4"), and the
-intended target IP on the Internet ("-i 131.159.74.67") and
-"gnunet-vpn" will tell you which IP address in the range of your
-VPN tunnel was mapped.
-
-@command{gnunet-vpn} can also be used to access "internal" services
-offered by GNUnet nodes. So if you happen to know a peer and a
-service offered by that peer, you can create an IP tunnel to
-that peer by specifying the peer's identity, service name and
-protocol (--tcp or --udp) and you will again receive an IP address
-that will terminate at the respective peer's service.
+++ /dev/null
-@node Vocabulary
-@chapter Vocabulary
-
-@menu
-* Words and characters::
-* Technical Assumptions::
-@end menu
-
-@node Words and characters
-@section Words and characters
-
-Throughout this document we use certain words and characters.
-
-@enumerate
-@item
-``@command{#}'' in example code blocks describes commands, ie comments.
-
-@example
-# Do the foobar thing:
-$ make foobar
-@end example
-
-@item
-Dollarsign ``@command{$}'' in example code blocks describes commands you
-execute as unprivileged users.
-
-@example
-$ cd foo; ./configure --example-switch
-@end example
-
-@item
-Backslash ``@command{\}'' describes linebreaks.
-
-@example
-./configure --foo --bar --baz \
- --short-loop
-@end example
-
-...expands to @code{./configure --foo --bar --baz --short-loop}
-
-@end enumerate
-
-@node Technical Assumptions
-@section Technical Assumptions
-
-@c Is it really assuming Bash (ie Bash extensions of POSIX being used)?
-The shell on GNU systems is assumed to be Bash.
+++ /dev/null
-html, body {
- font-size: 1em;
- text-align: left;
- text-decoration: none;
-}
-html { background-color: #e7e7e7; }
-
-body {
- max-width: 74.92em;
- margin: 0 auto;
- padding: .5em 1em 1em 1em;
- background-color: white;
- border: .1em solid #c0c0c0;
-}
-
-h1, h2, h3, h4 { color: #333; }
-h5, h6, dt { color: #222; }
-
-
-a h3 {
- color: #005090;
-}
-
-a[href] { color: #005090; }
-a[href]:visited { color: #100070; }
-a[href]:active, a[href]:hover {
- color: #100070;
- text-decoration: none;
-}
-
-.linkrow {
- margin: 3em 0;
-}
-
-.linkrow {
- text-align: center;
-}
-
-div.example { padding: .8em 1.2em .4em; }
-pre.example { padding: .8em 1.2em; }
-div.example, pre.example {
- margin: 1em 0 1em 3% ;
- -webkit-border-radius: .3em;
- -moz-border-radius: .3em;
- border-radius: .3em;
- border: 1px solid #d4cbb6;
- background-color: #f2efe4;
-}
-div.example > pre.example {
- padding: 0 0 .4em;
- margin: 0;
- border: none;
-}
-
-
-/* This makes the very long tables of contents in Gnulib and other
- manuals easier to read. */
-.contents ul, .shortcontents ul { font-weight: bold; }
-.contents ul ul, .shortcontents ul ul { font-weight: normal; }
-.contents ul { list-style: none; }
-
-/* For colored navigation bars (Emacs manual): make the bar extend
- across the whole width of the page and give it a decent height. */
-.header, .node { margin: 0 -1em; padding: 0 1em; }
-.header p, .node p { line-height: 2em; }
-
-/* For navigation links */
-.node a, .header a { display: inline-block; line-height: 2em; }
-.node a:hover, .header a:hover { background: #f2efe4; }
-
-table.cartouche {
- border-collapse: collapse;
- border-color: darkred;
- border-style: solid;
- border-width: 3px;
-}
--- /dev/null
+# This Makefile.am is in the public domain
+docdir = $(datadir)/doc/gnunet/
+
+infoimagedir = $(infodir)/images
+
+#DOT_FILES = images/$(wildcard *.dot)
+
+#DOT_VECTOR_GRAPHICS = \
+# $(DOT_FILES:%.dot=%.eps) \
+# $(DOT_FILES:%.dot=%.pdf)
+
+AM_MAKEINFOHTMLFLAGS = --no-split --css-ref=docstyle.css
+
+dist_infoimage_DATA = \
+ images/gnunet-gtk-0-10-gns-a-done.png \
+ images/gnunet-gtk-0-10-gns-a.png \
+ images/daemon_lego_block.png \
+ images/gnunet-gtk-0-10-gns.png \
+ images/gnunet-0-10-peerinfo.png \
+ images/gnunet-gtk-0-10-identity.png \
+ images/gnunet-fs-gtk-0-10-star-tab.png \
+ images/gnunet-gtk-0-10.png \
+ images/gnunet-gtk-0-10-download-area.png \
+ images/gnunet-gtk-0-10-search-selected.png \
+ images/gnunet-gtk-0-10-fs-menu.png \
+ images/gnunet-gtk-0-10-traffic.png \
+ images/gnunet-gtk-0-10-fs.png \
+ images/gnunet-namestore-gtk-phone.png \
+ images/gnunet-gtk-0-10-fs-publish-editing.png \
+ images/gnunet-namestore-gtk-vpn.png \
+ images/gnunet-gtk-0-10-fs-published.png \
+ images/gnunet-setup-exit.png \
+ images/gnunet-gtk-0-10-fs-publish.png \
+ images/iceweasel-preferences.png \
+ images/gnunet-gtk-0-10-fs-publish-select.png \
+ images/iceweasel-proxy.png \
+ images/gnunet-gtk-0-10-fs-publish-with-file_0.png \
+ images/service_lego_block.png \
+ images/gnunet-gtk-0-10-fs-publish-with-file.png \
+ images/service_stack.png \
+ images/gnunet-gtk-0-10-fs-search.png \
+ images/gnunet-tutorial-service.png \
+ images/gnunet-tutorial-system.png \
+ images/daemon_lego_block.svg \
+ images/lego_stack.svg \
+ images/service_lego_block.svg \
+ images/structure.dot
+
+# images/$(wildcard *.png) \
+# images/$(wildcard *.svg)
+# $(DOT_FILES:%.dot=%.png)
+
+#DOT_OPTIONS = \
+# -Gratio=.9 -Gnodesep=.005 -Granksep=.00005 \
+# -Nfontsite=9 -Nheight=.1 -Nwidth=.1
+
+# .dot.png:
+# $(AM_V_DOT)$(DOT) -Tpng $(DOT_OPTIONS) < "$<" > "$(srcdir)/$@.tmp"; \
+# mv "$(srcdir)/$@.tmp" "$(srcdir)/$@"
+
+# .dot.pdf:
+# $(AM_V_DOT)$(DOT) -Tpdf $(DOT_OPTIONS) < "$<" > "$(srcdir)/$@.tmp"; \
+# mv "$(srcdir)/$@.tmp" "$(srcdir)/$@"
+
+# .dot.eps:
+# $(AM_V_DOT)$(DOT) -Teps $(DOT_OPTIONS) < "$<" > "$(srcdir)/$@.tmp"; \
+# mv "$(srcdir)/$@.tmp" "$(srcdir)/$@"
+
+# .png.eps:
+# $(AM_V_GEN)convert "$<" "$@-tmp.eps"; \
+# mv "$@-tmp.eps" "$@"
+
+# pdf-local: $(DOT_FILES=%.dot=$(top_srcdir)/%.pdf)
+# info-local: $(DOT_FILES=%.dot=$(top_srcdir)/%.png)
+# ps-local: $(DOT_FILES=%.dot=$(top_srcdir)/%.eps) \
+# $(top_srcdir)/%D%/images/coreutils-size-map.eps
+# dvi-local: ps-local
+
+gnunet_tutorial_examples = \
+ 001.c \
+ 002.c \
+ 003.c \
+ 004.c \
+ 005.c \
+ 006.c \
+ 007.c \
+ 008.c \
+ 009.c \
+ 010.c \
+ 011.c \
+ 012.c \
+ 013.c \
+ 013.1.c \
+ 014.c \
+ 015.c \
+ 016.c \
+ 017.c \
+ 018.c \
+ 019.c \
+ 020.c \
+ 021.c \
+ 022.c \
+ 023.c \
+ 024.c \
+ 025.c \
+ 026.c
+
+info_TEXINFOS = \
+ gnunet.texi \
+ gnunet-c-tutorial.texi
+
+gnunet_TEXINFOS = \
+ chapters/developer.texi \
+ chapters/installation.texi \
+ chapters/philosophy.texi \
+ chapters/user.texi \
+ chapters/vocabulary.texi \
+ fdl-1.3.texi \
+ gpl-3.0.texi
+
+EXTRA_DIST = \
+ $(gnunet_TEXINFOS) \
+ $(gnunet_tutorial_examples) \
+ docstyle.css
+
+
+# $(DOT_FILES) \
+# $(DOT_VECTOR_GRAPHICS)
+
+DISTCLEANFILES = \
+ gnunet.cps \
+ gnunet-c-tutorial.cps \
+ chapters/developer.cps \
+ chapters/installation.cps \
+ chapter/philosophy.cps \
+ chapters/user.cps \
+ fdl-1.3.cps \
+ gpl-3.0.cps
+
+# if HAVE_EXTENDED_DOCUMENTATION_BUILDING
+daemon_lego_block.png: images/daemon_lego_block.svg
+ convert images/daemon_lego_block.svg images/daemon_lego_block.png &&
+ pngcrush images/daemon_lego_block.png images/daemon_lego_block.png
+
+service_lego_block.png: images/service_lego_block.svg
+ convert images/service_lego_block.svg images/service_lego_block.png &&
+ pngcrush images/service_lego_block.png images/serivce_lego_block.png
+
+lego_stack.png: images/lego_stack.svg
+ convert images/lego_stack.svg images/lego_stack.png &&
+ pngcrush images/lego_stack.png images/lego_stack.png
+
+# FIXME: The usage of 'date' strings causes a warning.
+# version.texi:
+# echo "@set UPDATED $(date +'%d %B %Y')" > $@
+# echo "@set UPDATED-MONTH $(date +'%B %Y')" >> $@
+# echo "@set EDITION $(PACKAGE_VERSION)" >> $@
+# echo "@set VERSION $(PACKAGE_VERSION)" >> $@
+
+# Workaround for makeinfo error. Whcih in turn introduces more
+# date-related 'warnings'. Well.
+version2.texi:
+ echo "@set UPDATED $(date +'%d %B %Y')" > $@
+ echo "@set UPDATED-MONTH $(date +'%B %Y')" >> $@
+ echo "@set EDITION $(PACKAGE_VERSION)" >> $@
+ echo "@set VERSION $(PACKAGE_VERSION)" >> $@
+
+# FIXME: rm *.html and *.pdf
+#doc-clean:
+# @rm *.aux *.log *.toc *.cp *.cps
+
+doc-all-install:
+ @mkdir -p $(DESTDIR)/$(docdir)
+ @mkdir -p $(DESTDIR)/$(infoimagedir)
+ @mkdir -p $(DESTDIR)/$(infodir)
+ @install -m 0755 gnunet.pdf $(DESTDIR)/$(docdir)
+ @install -m 0755 gnunet-c-tutorial.pdf $(DESTDIR)/$(docdir)
+ @install -m 0755 gnunet-c-tutorial.info $(DESTDIR)/$(infodir)
+ @install -m 0755 gnunet.info $(DESTDIR)/$(infodir)
+ @install gnunet.html $(DESTDIR)/$(docdir)
+ @install gnunet-c-tutorial.html $(DESTDIR)/$(docdir)
+
+# @cp -r images $(DESTDIR)/$(infoimagedir)
+
+# TODO: Add more to clean.
+clean:
+ @rm gnunet.pdf
+ @rm gnunet.html
+ @rm gnunet.info
+ @rm gnunet.info-1
+ @rm gnunet.info-2
+ @rm gnunet.info-3
+ @rm gnunet-c-tutorial.pdf
+ @rm gnunet-c-tutorial.info
+ @rm gnunet-c-tutorial.html
+ @rm -r gnunet.t2p
+ @rm -r gnunet-c-tutorial.t2p
+
+# CLEANFILES = \
+# gnunet.log \
+# gnunet-c-tutorial.log \
+# $(wildcard *.aux) \
+# $(wildcard *.toc) \
+# $(wildcard *.cp) \
+# $(wildcard *.cps)
+
+#.PHONY: version.texi
+# if HAVE_EXTENDED_DOCUMENTATION_BUILDING_PDF
+
+# if HAVE_EXTENDED_DOCUMENTATION_BUILDING_HTML
+
+# endif
+# endif
+# endif
--- /dev/null
+To be moved to an appropriate section of "how to write documentation" or
+"how to contribute to the documentation":
+
+1. When writing documentation, please use gender-neutral wording when
+ referring to people, such as singular “they”, “their”, “them”, and
+ so forth. -> https://en.wikipedia.org/wiki/Singular_they
+
+2. Keep line length below 74 characters.
+
+3. Do not use tab characters (see chapter 2.1 texinfo manual)
+* What's left to do
+
+- Which Texlive modules are needed? Decrease the size.
+- Update the content of gnunet documentation.
+
+* How to use (hack) on this
+
+** with guix
+
+Adjust accordingly, ie read the Guix Documentation:
+setenv GUIX_PACKAGE_PATH "gnunet/contrib/packages/guix/packages"
+guix environment gnunet-doc
+and
+guix build -f contrib/packages/guix/gnunet-doc.scm
+
+** without guix
+
+You need to have Texinfo and Texlive in your path.
+sh bootstrap
+./configure --enable-documentation
+cd doc
+make (format you want)
+
+for example: make html, make info, make pdf
+
+* structure (relations)
+
+** gnunet.texi
+ -> chapters/developer.texi
+ -> chapters/installation.texi
+ -> chapters/philosophy.texi
+ -> chapters/user.texi
+ -> chapters/vocabulary.texi
+ -> images/*
+ -> gpl-3.0.texi
+ -> fdl-1.3.texi
+
+** gnunet-c-tutorial.texi
+ -> figs/Service.pdf
+ -> figs/System.pdf
+ -> tutorial-examples/*.c
+ -> gpl-3.0.texi
+ -> fdl-1.3.texi
+
+- gnunet-c-tutorial-v1.pdf: original LaTeX "gnunet-c-tutorial.pdf".
+- man folder: the man pages.
+- doxygen folder
+- outdated-and-old-installation-instructions.txt: self described within the file.
+
+
+Use `gendocs', add to the manual/ directory of the web site.
+
+ $ cd doc
+ $ gendocs.sh gnunet "GNUnet 0.10.X Reference Manual"
--- /dev/null
+@c ***********************************************************************
+@node GNUnet Developer Handbook
+@chapter GNUnet Developer Handbook
+
+This book is intended to be an introduction for programmers that want to
+extend the GNUnet framework. GNUnet is more than a simple peer-to-peer
+application. For developers, GNUnet is:
+
+@itemize @bullet
+@item Free software under the GNU General Public License, with a community
+that believes in the GNU philosophy
+@item
+A set of standards, including coding conventions and architectural rules
+@item
+A set of layered protocols, both specifying the communication between
+peers as well as the communication between components of a single peer.
+@item
+A set of libraries with well-defined APIs suitable for writing extensions
+@end itemize
+
+In particular, the architecture specifies that a peer consists of many
+processes communicating via protocols. Processes can be written in almost
+any language. C and Java APIs exist for accessing existing services and
+for writing extensions. It is possible to write extensions in other
+languages by implementing the necessary IPC protocols.
+
+GNUnet can be extended and improved along many possible dimensions, and
+anyone interested in free software and freedom-enhancing networking is
+welcome to join the effort. This developer handbook attempts to provide
+an initial introduction to some of the key design choices and central
+components of the system. This manual is far from complete, and we
+welcome informed contributions, be it in the form of new chapters or
+insightful comments.
+
+However, the website is experiencing a constant onslaught of sophisticated
+link-spam entered manually by exploited workers solving puzzles and
+customizing text. To limit this commercial defacement, we are strictly
+moderating comments and have disallowed "normal" users from posting new
+content. However, this is really only intended to keep the spam at bay. If
+you are a real user or aspiring developer, please drop us a note
+(IRC, e-mail, contact form) with your user profile ID number included.
+We will then relax these restrictions on your account. We're sorry for
+this inconvenience; however, few people would want to read this site
+if 99% of it was advertisements for bogus websites.
+
+
+
+@c ***********************************************************************
+
+
+
+
+
+
+
+
+@menu
+* Developer Introduction::
+* Code overview::
+* System Architecture::
+* Subsystem stability::
+* Naming conventions and coding style guide::
+* Build-system::
+* Developing extensions for GNUnet using the gnunet-ext template::
+* Writing testcases::
+* GNUnet's TESTING library::
+* Performance regression analysis with Gauger::
+* GNUnet's TESTBED Subsystem::
+* libgnunetutil::
+* The Automatic Restart Manager (ARM)::
+* GNUnet's TRANSPORT Subsystem::
+* NAT library::
+* Distance-Vector plugin::
+* SMTP plugin::
+* Bluetooth plugin::
+* WLAN plugin::
+* The ATS Subsystem::
+* GNUnet's CORE Subsystem::
+* GNUnet's CADET subsystem::
+* GNUnet's NSE subsystem::
+* GNUnet's HOSTLIST subsystem::
+* GNUnet's IDENTITY subsystem::
+* GNUnet's NAMESTORE Subsystem::
+* GNUnet's PEERINFO subsystem::
+* GNUnet's PEERSTORE subsystem::
+* GNUnet's SET Subsystem::
+* GNUnet's STATISTICS subsystem::
+* GNUnet's Distributed Hash Table (DHT)::
+* The GNU Name System (GNS)::
+* The GNS Namecache::
+* The REVOCATION Subsystem::
+* GNUnet's File-sharing (FS) Subsystem::
+* GNUnet's REGEX Subsystem::
+@end menu
+
+@node Developer Introduction
+@section Developer Introduction
+
+This developer handbook is intended as first introduction to GNUnet for
+new developers that want to extend the GNUnet framework. After the
+introduction, each of the GNUnet subsystems (directories in the
+@file{src/} tree) is (supposed to be) covered in its own chapter. In
+addition to this documentation, GNUnet developers should be aware of the
+services available on the GNUnet server to them.
+
+New developers can have a look a the GNUnet tutorials for C and java
+available in the @file{src/} directory of the repository or under the
+following links:
+
+@c ** FIXME: Link to files in source, not online.
+@c ** FIXME: Where is the Java tutorial?
+@itemize @bullet
+@item @uref{https://gnunet.org/git/gnunet.git/plain/doc/gnunet-c-tutoria
+l.pdf, GNUnet C tutorial}
+@item GNUnet Java tutorial
+@end itemize
+
+In addition to this book, the GNUnet server contains various resources for
+GNUnet developers. They are all conveniently reachable via the "Developer"
+entry in the navigation menu. Some additional tools (such as static
+analysis reports) require a special developer access to perform certain
+operations. If you feel you need access, you should contact
+@uref{http://grothoff.org/christian/, Christian Grothoff},
+GNUnet's maintainer.
+
+The public subsystems on the GNUnet server that help developers are:
+
+@itemize @bullet
+@item The Version control system keeps our code and enables distributed
+development. Only developers with write access can commit code, everyone
+else is encouraged to submit patches to the
+@uref{https://lists.gnu.org/mailman/listinfo/gnunet-developers,
+GNUnet-developers mailinglist}.
+@item The GNUnet bugtracking system is used to track feature requests,
+open bug reports and their resolutions. Anyone can report bugs, only
+developers can claim to have fixed them.
+@item A buildbot is used to check GNUnet builds automatically on a range
+of platforms. Builds are triggered automatically after 30 minutes of no
+changes to Git.
+@item The current quality of our automated test suite is assessed using
+Code coverage analysis. This analysis is run daily; however the webpage
+is only updated if all automated tests pass at that time. Testcases that
+improve our code coverage are always welcome.
+@item We try to automatically find bugs using a static analysis scan.
+This scan is run daily; however the webpage is only updated if all
+automated tests pass at the time. Note that not everything that is
+flagged by the analysis is a bug, sometimes even good code can be marked
+as possibly problematic. Nevertheless, developers are encouraged to at
+least be aware of all issues in their code that are listed.
+@item We use Gauger for automatic performance regression visualization.
+Details on how to use Gauger are here.
+@item We use @uref{http://junit.org/, junit} to automatically test
+gnunet-java. Automatically generated, current reports on the test suite
+are here.
+@item We use Cobertura to generate test coverage reports for gnunet-java.
+Current reports on test coverage are here.
+@end itemize
+
+
+
+@c ***********************************************************************
+@menu
+* Project overview::
+@end menu
+
+@node Project overview
+@subsection Project overview
+
+The GNUnet project consists at this point of several sub-projects. This
+section is supposed to give an initial overview about the various
+sub-projects. Note that this description also lists projects that are far
+from complete, including even those that have literally not a single line
+of code in them yet.
+
+GNUnet sub-projects in order of likely relevance are currently:
+
+@table @asis
+
+@item gnunet Core of the P2P framework, including file-sharing, VPN and
+chat applications; this is what the developer handbook covers mostly
+@item gnunet-gtk Gtk+-based user interfaces, including gnunet-fs-gtk
+(file-sharing), gnunet-statistics-gtk (statistics over time),
+gnunet-peerinfo-gtk (information about current connections and known
+peers), gnunet-chat-gtk (chat GUI) and gnunet-setup (setup tool for
+"everything")
+@item gnunet-fuse Mounting directories shared via GNUnet's file-sharing
+on Linux
+@item gnunet-update Installation and update tool
+@item gnunet-ext Template for starting 'external' GNUnet projects
+@item gnunet-java Java APIs for writing GNUnet services and applications
+@c ** FIXME: Point to new website repository once we have it:
+@c ** @item svn/gnunet-www/ Code and media helping drive the GNUnet
+website
+@item eclectic Code to run
+GNUnet nodes on testbeds for research, development, testing and evaluation
+@c ** FIXME: Solve the status and location of gnunet-qt
+@item gnunet-qt qt-based GNUnet GUI (dead?)
+@item gnunet-cocoa cocoa-based GNUnet GUI (dead?)
+
+@end table
+
+We are also working on various supporting libraries and tools:
+@c ** FIXME: What about gauger, and what about libmwmodem?
+
+@table @asis
+@item libextractor GNU libextractor (meta data extraction)
+@item libmicrohttpd GNU libmicrohttpd (embedded HTTP(S) server library)
+@item gauger Tool for performance regression analysis
+@item monkey Tool for automated debugging of distributed systems
+@item libmwmodem Library for accessing satellite connection quality
+reports
+@end table
+
+Finally, there are various external projects (see links for a list of
+those that have a public website) which build on top of the GNUnet
+framework.
+
+@c ***********************************************************************
+@node Code overview
+@section Code overview
+
+This section gives a brief overview of the GNUnet source code.
+Specifically, we sketch the function of each of the subdirectories in
+the @file{gnunet/src/} directory. The order given is roughly bottom-up
+(in terms of the layers of the system).
+
+@table @asis
+@item util/ --- libgnunetutil Library with general utility functions, all
+GNUnet binaries link against this library. Anything from memory
+allocation and data structures to cryptography and inter-process
+communication. The goal is to provide an OS-independent interface and
+more 'secure' or convenient implementations of commonly used primitives.
+The API is spread over more than a dozen headers, developers should study
+those closely to avoid duplicating existing functions.
+@item hello/ --- libgnunethello HELLO messages are used to
+describe under which addresses a peer can be reached (for example,
+protocol, IP, port). This library manages parsing and generating of HELLO
+messages.
+@item block/ --- libgnunetblock The DHT and other components of GNUnet
+store information in units called 'blocks'. Each block has a type and the
+type defines a particular format and how that binary format is to be
+linked to a hash code (the key for the DHT and for databases). The block
+library is a wapper around block plugins which provide the necessary
+functions for each block type.
+@item statistics/ The statistics service enables associating
+values (of type uint64_t) with a componenet name and a string. The main
+uses is debugging (counting events), performance tracking and user
+entertainment (what did my peer do today?).
+@item arm/ The automatic-restart-manager (ARM) service
+is the GNUnet master service. Its role is to start gnunet-services, to
+re-start them when they crashed and finally to shut down the system when
+requested.
+@item peerinfo/ The peerinfo service keeps track of which peers are known
+to the local peer and also tracks the validated addresses for each peer
+(in the form of a HELLO message) for each of those peers. The peer is not
+necessarily connected to all peers known to the peerinfo service.
+Peerinfo provides persistent storage for peer identities --- peers are
+not forgotten just because of a system restart.
+@item datacache/ --- libgnunetdatacache The datacache
+library provides (temporary) block storage for the DHT. Existing plugins
+can store blocks in Sqlite, Postgres or MySQL databases. All data stored
+in the cache is lost when the peer is stopped or restarted (datacache
+uses temporary tables).
+@item datastore/ The datastore service stores file-sharing blocks in
+databases for extended periods of time. In contrast to the datacache, data
+is not lost when peers restart. However, quota restrictions may still
+cause old, expired or low-priority data to be eventually discarded.
+Existing plugins can store blocks in Sqlite, Postgres or MySQL databases.
+@item template/ Template for writing a new service. Does nothing.
+@item ats/ The automatic transport
+selection (ATS) service is responsible for deciding which address (i.e.
+which transport plugin) should be used for communication with other peers,
+and at what bandwidth.
+@item nat/ --- libgnunetnat Library that provides basic
+functions for NAT traversal. The library supports NAT traversal with
+manual hole-punching by the user, UPnP and ICMP-based autonomous NAT
+traversal. The library also includes an API for testing if the current
+configuration works and the @code{gnunet-nat-server} which provides an
+external service to test the local configuration.
+@item fragmentation/ --- libgnunetfragmentation Some
+transports (UDP and WLAN, mostly) have restrictions on the maximum
+transfer unit (MTU) for packets. The fragmentation library can be used to
+break larger packets into chunks of at most 1k and transmit the resulting
+fragments reliabily (with acknowledgement, retransmission, timeouts,
+etc.).
+@item transport/ The transport service is responsible for managing the
+basic P2P communication. It uses plugins to support P2P communication
+over TCP, UDP, HTTP, HTTPS and other protocols.The transport service
+validates peer addresses, enforces bandwidth restrictions, limits the
+total number of connections and enforces connectivity restrictions (i.e.
+friends-only).
+@item peerinfo-tool/
+This directory contains the gnunet-peerinfo binary which can be used to
+inspect the peers and HELLOs known to the peerinfo service.
+@item core/ The core
+service is responsible for establishing encrypted, authenticated
+connections with other peers, encrypting and decrypting messages and
+forwarding messages to higher-level services that are interested in them.
+@item testing/ ---
+libgnunettesting The testing library allows starting (and stopping) peers
+for writing testcases.@
+It also supports automatic generation of configurations for peers
+ensuring that the ports and paths are disjoint. libgnunettesting is also
+the foundation for the testbed service
+@item testbed/ The testbed service is
+used for creating small or large scale deployments of GNUnet peers for
+evaluation of protocols. It facilitates peer depolyments on multiple
+hosts (for example, in a cluster) and establishing varous network
+topologies (both underlay and overlay).
+@item nse/ The network size estimation (NSE) service
+implements a protocol for (securely) estimating the current size of the
+P2P network.
+@item dht/ The distributed hash table (DHT) service provides a
+distributed implementation of a hash table to store blocks under hash
+keys in the P2P network.
+@item hostlist/ The hostlist service allows learning about
+other peers in the network by downloading HELLO messages from an HTTP
+server, can be configured to run such an HTTP server and also implements
+a P2P protocol to advertise and automatically learn about other peers
+that offer a public hostlist server.
+@item topology/ The topology service is responsible for
+maintaining the mesh topology. It tries to maintain connections to friends
+(depending on the configuration) and also tries to ensure that the peer
+has a decent number of active connections at all times. If necessary, new
+connections are added. All peers should run the topology service,
+otherwise they may end up not being connected to any other peer (unless
+some other service ensures that core establishes the required
+connections). The topology service also tells the transport service which
+connections are permitted (for friend-to-friend networking)
+@item fs/ The file-sharing (FS) service implements GNUnet's
+file-sharing application. Both anonymous file-sharing (using gap) and
+non-anonymous file-sharing (using dht) are supported.
+@item cadet/ The CADET
+service provides a general-purpose routing abstraction to create
+end-to-end encrypted tunnels in mesh networks. We wrote a paper
+documenting key aspects of the design.
+@item tun/ --- libgnunettun Library for building IPv4, IPv6
+packets and creating checksums for UDP, TCP and ICMP packets. The header
+defines C structs for common Internet packet formats and in particular
+structs for interacting with TUN (virtual network) interfaces.
+@item mysql/ ---
+libgnunetmysql Library for creating and executing prepared MySQL
+statements and to manage the connection to the MySQL database.
+Essentially a lightweight wrapper for the interaction between GNUnet
+components and libmysqlclient.
+@item dns/ Service that allows intercepting and modifying DNS requests of
+the local machine. Currently used for IPv4-IPv6 protocol translation
+(DNS-ALG) as implemented by "pt/" and for the GNUnet naming system. The
+service can also be configured to offer an exit service for DNS traffic.
+@item vpn/ The virtual
+public network (VPN) service provides a virtual tunnel interface (VTUN)
+for IP routing over GNUnet. Needs some other peers to run an "exit"
+service to work.
+Can be activated using the "gnunet-vpn" tool or integrated with DNS using
+the "pt" daemon.
+@item exit/ Daemon to allow traffic from the VPN to exit this
+peer to the Internet or to specific IP-based services of the local peer.
+Currently, an exit service can only be restricted to IPv4 or IPv6, not to
+specific ports and or IP address ranges. If this is not acceptable,
+additional firewall rules must be added manually. exit currently only
+works for normal UDP, TCP and ICMP traffic; DNS queries need to leave the
+system via a DNS service.
+@item pt/ protocol translation daemon. This daemon enables 4-to-6,
+6-to-4, 4-over-6 or 6-over-4 transitions for the local system. It
+essentially uses "DNS" to intercept DNS replies and then maps results to
+those offered by the VPN, which then sends them using mesh to some daemon
+offering an appropriate exit service.
+@item identity/ Management of egos (alter egos) of a user; identities are
+essentially named ECC private keys and used for zones in the GNU name
+system and for namespaces in file-sharing, but might find other uses later
+@item revocation/ Key revocation service, can be used to revoke the
+private key of an identity if it has been compromised
+@item namecache/ Cache
+for resolution results for the GNU name system; data is encrypted and can
+be shared among users, loss of the data should ideally only result in a
+performance degradation (persistence not required)
+@item namestore/ Database
+for the GNU name system with per-user private information, persistence
+required
+@item gns/ GNU name system, a GNU approach to DNS and PKI.
+@item dv/ A plugin
+for distance-vector (DV)-based routing. DV consists of a service and a
+transport plugin to provide peers with the illusion of a direct P2P
+connection for connections that use multiple (typically up to 3) hops in
+the actual underlay network.
+@item regex/ Service for the (distributed) evaluation of
+regular expressions.
+@item scalarproduct/ The scalar product service offers an
+API to perform a secure multiparty computation which calculates a scalar
+product between two peers without exposing the private input vectors of
+the peers to each other.
+@item consensus/ The consensus service will allow a set
+of peers to agree on a set of values via a distributed set union
+computation.
+@item rest/ The rest API allows access to GNUnet services using RESTful
+interaction. The services provide plugins that can exposed by the rest
+server.
+@item experimentation/ The experimentation daemon coordinates distributed
+experimentation to evaluate transport and ats properties
+@end table
+
+@c ***********************************************************************
+@node System Architecture
+@section System Architecture
+
+GNUnet developers like legos. The blocks are indestructible, can be
+stacked together to construct complex buildings and it is generally easy
+to swap one block for a different one that has the same shape. GNUnet's
+architecture is based on legos:
+
+@c images here
+
+This chapter documents the GNUnet lego system, also known as GNUnet's
+system architecture.
+
+The most common GNUnet component is a service. Services offer an API (or
+several, depending on what you count as "an API") which is implemented as
+a library. The library communicates with the main process of the service
+using a service-specific network protocol. The main process of the service
+typically doesn't fully provide everything that is needed --- it has holes
+to be filled by APIs to other services.
+
+A special kind of component in GNUnet are user interfaces and daemons.
+Like services, they have holes to be filled by APIs of other services.
+Unlike services, daemons do not implement their own network protocol and
+they have no API:
+
+The GNUnet system provides a range of services, daemons and user
+interfaces, which are then combined into a layered GNUnet instance (also
+known as a peer).
+
+Note that while it is generally possible to swap one service for another
+compatible service, there is often only one implementation. However,
+during development we often have a "new" version of a service in parallel
+with an "old" version. While the "new" version is not working, developers
+working on other parts of the service can continue their development by
+simply using the "old" service. Alternative design ideas can also be
+easily investigated by swapping out individual components. This is
+typically achieved by simply changing the name of the "BINARY" in the
+respective configuration section.
+
+Key properties of GNUnet services are that they must be separate
+processes and that they must protect themselves by applying tight error
+checking against the network protocol they implement (thereby achieving a
+certain degree of robustness).
+
+On the other hand, the APIs are implemented to tolerate failures of the
+service, isolating their host process from errors by the service. If the
+service process crashes, other services and daemons around it should not
+also fail, but instead wait for the service process to be restarted by
+ARM.
+
+
+@c ***********************************************************************
+@node Subsystem stability
+@section Subsystem stability
+
+This page documents the current stability of the various GNUnet
+subsystems. Stability here describes the expected degree of compatibility
+with future versions of GNUnet. For each subsystem we distinguish between
+compatibility on the P2P network level (communication protocol between
+peers), the IPC level (communication between the service and the service
+library) and the API level (stability of the API). P2P compatibility is
+relevant in terms of which applications are likely going to be able to
+communicate with future versions of the network. IPC communication is
+relevant for the implementation of language bindings that re-implement the
+IPC messages. Finally, API compatibility is relevant to developers that
+hope to be able to avoid changes to applications build on top of the APIs
+of the framework.
+
+The following table summarizes our current view of the stability of the
+respective protocols or APIs:
+
+@multitable @columnfractions .20 .20 .20 .20
+@headitem Subsystem @tab P2P @tab IPC @tab C API
+@item util @tab n/a @tab n/a @tab stable
+@item arm @tab n/a @tab stable @tab stable
+@item ats @tab n/a @tab unstable @tab testing
+@item block @tab n/a @tab n/a @tab stable
+@item cadet @tab testing @tab testing @tab testing
+@item consensus @tab experimental @tab experimental @tab experimental
+@item core @tab stable @tab stable @tab stable
+@item datacache @tab n/a @tab n/a @tab stable
+@item datastore @tab n/a @tab stable @tab stable
+@item dht @tab stable @tab stable @tab stable
+@item dns @tab stable @tab stable @tab stable
+@item dv @tab testing @tab testing @tab n/a
+@item exit @tab testing @tab n/a @tab n/a
+@item fragmentation @tab stable @tab n/a @tab stable
+@item fs @tab stable @tab stable @tab stable
+@item gns @tab stable @tab stable @tab stable
+@item hello @tab n/a @tab n/a @tab testing
+@item hostlist @tab stable @tab stable @tab n/a
+@item identity @tab stable @tab stable @tab n/a
+@item multicast @tab experimental @tab experimental @tab experimental
+@item mysql @tab stable @tab n/a @tab stable
+@item namestore @tab n/a @tab stable @tab stable
+@item nat @tab n/a @tab n/a @tab stable
+@item nse @tab stable @tab stable @tab stable
+@item peerinfo @tab n/a @tab stable @tab stable
+@item psyc @tab experimental @tab experimental @tab experimental
+@item pt @tab n/a @tab n/a @tab n/a
+@item regex @tab stable @tab stable @tab stable
+@item revocation @tab stable @tab stable @tab stable
+@item social @tab experimental @tab experimental @tab experimental
+@item statistics @tab n/a @tab stable @tab stable
+@item testbed @tab n/a @tab testing @tab testing
+@item testing @tab n/a @tab n/a @tab testing
+@item topology @tab n/a @tab n/a @tab n/a
+@item transport @tab stable @tab stable @tab stable
+@item tun @tab n/a @tab n/a @tab stable
+@item vpn @tab testing @tab n/a @tab n/a
+@end multitable
+
+Here is a rough explanation of the values:
+
+@table @samp
+@item stable
+No incompatible changes are planned at this time; for IPC/APIs, if
+there are incompatible changes, they will be minor and might only require
+minimal changes to existing code; for P2P, changes will be avoided if at
+all possible for the 0.10.x-series
+
+@item testing
+No incompatible changes are
+planned at this time, but the code is still known to be in flux; so while
+we have no concrete plans, our expectation is that there will still be
+minor modifications; for P2P, changes will likely be extensions that
+should not break existing code
+
+@item unstable
+Changes are planned and will happen; however, they
+will not be totally radical and the result should still resemble what is
+there now; nevertheless, anticipated changes will break protocol/API
+compatibility
+
+@item experimental
+Changes are planned and the result may look nothing like
+what the API/protocol looks like today
+
+@item unknown
+Someone should think about where this subsystem headed
+
+@item n/a
+This subsystem does not have an API/IPC-protocol/P2P-protocol
+@end table
+
+@c ***********************************************************************
+@node Naming conventions and coding style guide
+@section Naming conventions and coding style guide
+
+Here you can find some rules to help you write code for GNUnet.
+
+
+
+@c ***********************************************************************
+@menu
+* Naming conventions::
+* Coding style::
+@end menu
+
+@node Naming conventions
+@subsection Naming conventions
+
+
+@c ***********************************************************************
+@menu
+* include files::
+* binaries::
+* logging::
+* configuration::
+* exported symbols::
+* private (library-internal) symbols (including structs and macros)::
+* testcases::
+* performance tests::
+* src/ directories::
+@end menu
+
+@node include files
+@subsubsection include files
+
+@itemize @bullet
+@item _lib: library without need for a process
+@item _service: library that needs a service process
+@item _plugin: plugin definition
+@item _protocol: structs used in network protocol
+@item exceptions:
+@itemize @bullet
+@item gnunet_config.h --- generated
+@item platform.h --- first included
+@item plibc.h --- external library
+@item gnunet_common.h --- fundamental routines
+@item gnunet_directories.h --- generated
+@item gettext.h --- external library
+@end itemize
+@end itemize
+
+@c ***********************************************************************
+@node binaries
+@subsubsection binaries
+
+@itemize @bullet
+@item gnunet-service-xxx: service process (has listen socket)
+@item gnunet-daemon-xxx: daemon process (no listen socket)
+@item gnunet-helper-xxx[-yyy]: SUID helper for module xxx
+@item gnunet-yyy: command-line tool for end-users
+@item libgnunet_plugin_xxx_yyy.so: plugin for API xxx
+@item libgnunetxxx.so: library for API xxx
+@end itemize
+
+@c ***********************************************************************
+@node logging
+@subsubsection logging
+
+@itemize @bullet
+@item services and daemons use their directory name in GNUNET_log_setup
+(i.e. 'core') and log using plain 'GNUNET_log'.
+@item command-line tools use their full name in GNUNET_log_setup (i.e.
+'gnunet-publish') and log using plain 'GNUNET_log'.
+@item service access libraries log using 'GNUNET_log_from' and use
+'DIRNAME-api' for the component (i.e. 'core-api')
+@item pure libraries (without associated service) use 'GNUNET_log_from'
+with the component set to their library name (without lib or '.so'),
+which should also be their directory name (i.e. 'nat')
+@item plugins should use 'GNUNET_log_from' with the directory name and the
+plugin name combined to produce the component name (i.e. 'transport-tcp').
+@item logging should be unified per-file by defining a LOG macro with the
+appropriate arguments, along these lines:@ #define LOG(kind,...)
+GNUNET_log_from (kind, "example-api",__VA_ARGS__)
+@end itemize
+
+@c ***********************************************************************
+@node configuration
+@subsubsection configuration
+
+@itemize @bullet
+@item paths (that are substituted in all filenames) are in PATHS (have as
+few as possible)
+@item all options for a particular module (src/MODULE) are under [MODULE]
+@item options for a plugin of a module are under [MODULE-PLUGINNAME]
+@end itemize
+
+@c ***********************************************************************
+@node exported symbols
+@subsubsection exported symbols
+
+@itemize @bullet
+@item must start with "GNUNET_modulename_" and be defined in
+"modulename.c"
+@item exceptions: those defined in gnunet_common.h
+@end itemize
+
+@c ***********************************************************************
+@node private (library-internal) symbols (including structs and macros)
+@subsubsection private (library-internal) symbols (including structs and macros)
+
+@itemize @bullet
+@item must NOT start with any prefix
+@item must not be exported in a way that linkers could use them or@ other
+libraries might see them via headers; they must be either@
+declared/defined in C source files or in headers that are in@ the
+respective directory under src/modulename/ and NEVER be@ declared
+in src/include/.
+@end itemize
+
+@node testcases
+@subsubsection testcases
+
+@itemize @bullet
+@item must be called "test_module-under-test_case-description.c"
+@item "case-description" maybe omitted if there is only one test
+@end itemize
+
+@c ***********************************************************************
+@node performance tests
+@subsubsection performance tests
+
+@itemize @bullet
+@item must be called "perf_module-under-test_case-description.c"
+@item "case-description" maybe omitted if there is only one performance
+test
+@item Must only be run if HAVE_BENCHMARKS is satisfied
+@end itemize
+
+@c ***********************************************************************
+@node src/ directories
+@subsubsection src/ directories
+
+@itemize @bullet
+@item gnunet-NAME: end-user applications (i.e., gnunet-search, gnunet-arm)
+@item gnunet-service-NAME: service processes with accessor library (i.e.,
+gnunet-service-arm)
+@item libgnunetNAME: accessor library (_service.h-header) or standalone
+library (_lib.h-header)
+@item gnunet-daemon-NAME: daemon process without accessor library (i.e.,
+gnunet-daemon-hostlist) and no GNUnet management port
+@item libgnunet_plugin_DIR_NAME: loadable plugins (i.e.,
+libgnunet_plugin_transport_tcp)
+@end itemize
+
+@c ***********************************************************************
+@node Coding style
+@subsection Coding style
+
+@itemize @bullet
+@item GNU guidelines generally apply
+@item Indentation is done with spaces, two per level, no tabs
+@item C99 struct initialization is fine
+@item declare only one variable per line, so@
+
+@example
+int i; int j;
+@end example
+
+instead of
+
+@example
+int i,j;
+@end example
+
+This helps keep diffs small and forces developers to think precisely about
+the type of every variable. Note that @code{char *} is different from
+@code{const char*} and @code{int} is different from @code{unsigned int}
+or @code{uint32_t}. Each variable type should be chosen with care.
+
+@item While @code{goto} should generally be avoided, having a @code{goto}
+to the end of a function to a block of clean up statements (free, close,
+etc.) can be acceptable.
+
+@item Conditions should be written with constants on the left (to avoid
+accidental assignment) and with the 'true' target being either the
+'error' case or the significantly simpler continuation. For example:
+
+@example
+if (0 != stat ("filename," &sbuf)) @{ error(); @} else @{
+ /* handle normal case here */
+@}
+@end example
+
+instead of
+
+@example
+if (stat ("filename," &sbuf) == 0) @{
+ /* handle normal case here */
+@} else @{ error(); @}
+@end example
+
+If possible, the error clause should be terminated with a 'return' (or
+'goto' to some cleanup routine) and in this case, the 'else' clause
+should be omitted:
+
+@example
+if (0 != stat ("filename," &sbuf)) @{ error(); return; @}
+/* handle normal case here */
+@end example
+
+This serves to avoid deep nesting. The 'constants on the left' rule
+applies to all constants (including. @code{GNUNET_SCHEDULER_NO_TASK}),
+NULL, and enums). With the two above rules (constants on left, errors in
+'true' branch), there is only one way to write most branches correctly.
+
+@item Combined assignments and tests are allowed if they do not hinder
+code clarity. For example, one can write:
+
+@example
+if (NULL == (value = lookup_function())) @{ error(); return; @}
+@end example
+
+
+@item Use @code{break} and @code{continue} wherever possible to avoid
+deep(er) nesting. Thus, we would write:
+
+@example
+next = head; while (NULL != (pos = next)) @{ next = pos->next; if (!
+should_free (pos)) continue; GNUNET_CONTAINER_DLL_remove (head, tail, pos);
+GNUNET_free (pos); @}
+@end example
+
+
+instead of
+@example
+next = head; while (NULL != (pos = next)) @{ next =
+pos->next; if (should_free (pos)) @{
+ /* unnecessary nesting! */
+ GNUNET_CONTAINER_DLL_remove (head, tail, pos); GNUNET_free (pos); @} @}
+@end example
+
+
+@item We primarily use @code{for} and @code{while} loops. A @code{while}
+loop is used if the method for advancing in the loop is not a
+straightforward increment operation. In particular, we use:
+
+@example
+next = head;
+while (NULL != (pos = next))
+@{
+ next = pos->next;
+ if (! should_free (pos))
+ continue;
+ GNUNET_CONTAINER_DLL_remove (head, tail, pos);
+ GNUNET_free (pos);
+@}
+@end example
+
+
+to free entries in a list (as the iteration changes the structure of the
+list due to the free; the equivalent @code{for} loop does no longer
+follow the simple @code{for} paradigm of @code{for(INIT;TEST;INC)}).
+However, for loops that do follow the simple @code{for} paradigm we do
+use @code{for}, even if it involves linked lists:
+
+@example
+/* simple iteration over a linked list */
+for (pos = head; NULL != pos; pos = pos->next)
+@{
+ use (pos);
+@}
+@end example
+
+
+@item The first argument to all higher-order functions in GNUnet must be
+declared to be of type @code{void *} and is reserved for a closure. We do
+not use inner functions, as trampolines would conflict with setups that
+use non-executable stacks.@ The first statement in a higher-order
+function, which unusually should be part of the variable declarations,
+should assign the @code{cls} argument to the precise expected type.
+For example:
+
+@example
+int callback (void *cls, char *args) @{
+ struct Foo *foo = cls; int other_variables;
+
+ /* rest of function */
+@}
+@end example
+
+
+@item It is good practice to write complex @code{if} expressions instead
+of using deeply nested @code{if} statements. However, except for addition
+and multiplication, all operators should use parens. This is fine:
+
+@example
+if ( (1 == foo) || ((0 == bar) && (x != y)) )
+ return x;
+@end example
+
+
+However, this is not:
+@example
+if (1 == foo)
+ return x;
+if (0 == bar && x != y)
+ return x;
+@end example
+
+
+Note that splitting the @code{if} statement above is debateable as the
+@code{return x} is a very trivial statement. However, once the logic after
+the branch becomes more complicated (and is still identical), the "or"
+formulation should be used for sure.
+
+@item There should be two empty lines between the end of the function and
+the comments describing the following function. There should be a single
+empty line after the initial variable declarations of a function. If a
+function has no local variables, there should be no initial empty line. If
+a long function consists of several complex steps, those steps might be
+separated by an empty line (possibly followed by a comment describing the
+following step). The code should not contain empty lines in arbitrary
+places; if in doubt, it is likely better to NOT have an empty line (this
+way, more code will fit on the screen).
+@end itemize
+
+@c ***********************************************************************
+@node Build-system
+@section Build-system
+
+If you have code that is likely not to compile or build rules you might
+want to not trigger for most developers, use "if HAVE_EXPERIMENTAL" in
+your Makefile.am. Then it is OK to (temporarily) add non-compiling (or
+known-to-not-port) code.
+
+If you want to compile all testcases but NOT run them, run configure with
+the @code{--enable-test-suppression} option.
+
+If you want to run all testcases, including those that take a while, run
+configure with the @code{--enable-expensive-testcases} option.
+
+If you want to compile and run benchmarks, run configure with the
+@code{--enable-benchmarks} option.
+
+If you want to obtain code coverage results, run configure with the
+@code{--enable-coverage} option and run the coverage.sh script in
+@file{contrib/}.
+
+@c ***********************************************************************
+@node Developing extensions for GNUnet using the gnunet-ext template
+@section Developing extensions for GNUnet using the gnunet-ext template
+
+
+For developers who want to write extensions for GNUnet we provide the
+gnunet-ext template to provide an easy to use skeleton.
+
+gnunet-ext contains the build environment and template files for the
+development of GNUnet services, command line tools, APIs and tests.
+
+First of all you have to obtain gnunet-ext from git:
+
+@code{git clone https://gnunet.org/git/gnunet-ext.git}
+
+The next step is to bootstrap and configure it. For configure you have to
+provide the path containing GNUnet with
+@code{--with-gnunet=/path/to/gnunet} and the prefix where you want the
+install the extension using @code{--prefix=/path/to/install}:
+
+@example
+./bootstrap
+./configure --prefix=/path/to/install --with-gnunet=/path/to/gnunet
+@end example
+
+When your GNUnet installation is not included in the default linker search
+path, you have to add @code{/path/to/gnunet} to the file
+@file{/etc/ld.so.conf} and run @code{ldconfig} or your add it to the
+environmental variable @code{LD_LIBRARY_PATH} by using
+
+@code{export LD_LIBRARY_PATH=/path/to/gnunet/lib}
+
+@c ***********************************************************************
+@node Writing testcases
+@section Writing testcases
+
+Ideally, any non-trivial GNUnet code should be covered by automated
+testcases. Testcases should reside in the same place as the code that is
+being tested. The name of source files implementing tests should begin
+with "test_" followed by the name of the file that contains the code that
+is being tested.
+
+Testcases in GNUnet should be integrated with the autotools build system.
+This way, developers and anyone building binary packages will be able to
+run all testcases simply by running @code{make check}. The final
+testcases shipped with the distribution should output at most some brief
+progress information and not display debug messages by default. The
+success or failure of a testcase must be indicated by returning zero
+(success) or non-zero (failure) from the main method of the testcase. The
+integration with the autotools is relatively straightforward and only
+requires modifications to the @code{Makefile.am} in the directory
+containing the testcase. For a testcase testing the code in @code{foo.c}
+the @code{Makefile.am} would contain the following lines:
+
+@example
+check_PROGRAMS = test_foo TESTS = $(check_PROGRAMS) test_foo_SOURCES =
+test_foo.c test_foo_LDADD = $(top_builddir)/src/util/libgnunetutil.la
+@end example
+
+Naturally, other libraries used by the testcase may be specified in the
+@code{LDADD} directive as necessary.
+
+Often testcases depend on additional input files, such as a configuration
+file. These support files have to be listed using the EXTRA_DIST
+directive in order to ensure that they are included in the distribution.
+Example:
+
+@example
+EXTRA_DIST = test_foo_data.conf
+@end example
+
+Executing @code{make check} will run all testcases in the current
+directory and all subdirectories. Testcases can be compiled individually
+by running @code{make test_foo} and then invoked directly using
+@code{./test_foo}. Note that due to the use of plugins in GNUnet, it is
+typically necessary to run @code{make install} before running any
+testcases. Thus the canonical command @code{make check install} has to be
+changed to @code{make install check} for GNUnet.
+
+@c ***********************************************************************
+@node GNUnet's TESTING library
+@section GNUnet's TESTING library
+
+The TESTING library is used for writing testcases which involve starting a
+single or multiple peers. While peers can also be started by testcases
+using the ARM subsystem, using TESTING library provides an elegant way to
+do this. The configurations of the peers are auto-generated from a given
+template to have non-conflicting port numbers ensuring that peers'
+services do not run into bind errors. This is achieved by testing ports'
+availability by binding a listening socket to them before allocating them
+to services in the generated configurations.
+
+An another advantage while using TESTING is that it shortens the testcase
+startup time as the hostkeys for peers are copied from a pre-computed set
+of hostkeys instead of generating them at peer startup which may take a
+considerable amount of time when starting multiple peers or on an embedded
+processor.
+
+TESTING also allows for certain services to be shared among peers. This
+feature is invaluable when testing with multiple peers as it helps to
+reduce the number of services run per each peer and hence the total
+number of processes run per testcase.
+
+TESTING library only handles creating, starting and stopping peers.
+Features useful for testcases such as connecting peers in a topology are
+not available in TESTING but are available in the TESTBED subsystem.
+Furthermore, TESTING only creates peers on the localhost, however by
+using TESTBED testcases can benefit from creating peers across multiple
+hosts.
+
+@menu
+* API::
+* Finer control over peer stop::
+* Helper functions::
+* Testing with multiple processes::
+@end menu
+
+@c ***********************************************************************
+@node API
+@subsection API
+
+TESTING abstracts a group of peers as a TESTING system. All peers in a
+system have common hostname and no two services of these peers have a
+same port or a UNIX domain socket path.
+
+TESTING system can be created with the function
+@code{GNUNET_TESTING_system_create()} which returns a handle to the
+system. This function takes a directory path which is used for generating
+the configurations of peers, an IP address from which connections to the
+peers' services should be allowed, the hostname to be used in peers'
+configuration, and an array of shared service specifications of type
+@code{struct GNUNET_TESTING_SharedService}.
+
+The shared service specification must specify the name of the service to
+share, the configuration pertaining to that shared service and the
+maximum number of peers that are allowed to share a single instance of
+the shared service.
+
+TESTING system created with @code{GNUNET_TESTING_system_create()} chooses
+ports from the default range 12000 - 56000 while auto-generating
+configurations for peers. This range can be customised with the function
+@code{GNUNET_TESTING_system_create_with_portrange()}. This function is
+similar to @code{GNUNET_TESTING_system_create()} except that it take 2
+additional parameters --- the start and end of the port range to use.
+
+A TESTING system is destroyed with the funciton
+@code{GNUNET_TESTING_system_destory()}. This function takes the handle of
+the system and a flag to remove the files created in the directory used
+to generate configurations.
+
+A peer is created with the function
+@code{GNUNET_TESTING_peer_configure()}. This functions takes the system
+handle, a configuration template from which the configuration for the peer
+is auto-generated and the index from where the hostkey for the peer has to
+be copied from. When successfull, this function returs a handle to the
+peer which can be used to start and stop it and to obtain the identity of
+the peer. If unsuccessful, a NULL pointer is returned with an error
+message. This function handles the generated configuration to have
+non-conflicting ports and paths.
+
+Peers can be started and stopped by calling the functions
+@code{GNUNET_TESTING_peer_start()} and @code{GNUNET_TESTING_peer_stop()}
+respectively. A peer can be destroyed by calling the function
+@code{GNUNET_TESTING_peer_destroy}. When a peer is destroyed, the ports
+and paths in allocated in its configuration are reclaimed for usage in new
+peers.
+
+@c ***********************************************************************
+@node Finer control over peer stop
+@subsection Finer control over peer stop
+
+Using @code{GNUNET_TESTING_peer_stop()} is normally fine for testcases.
+However, calling this function for each peer is inefficient when trying to
+shutdown multiple peers as this function sends the termination signal to
+the given peer process and waits for it to terminate. It would be faster
+in this case to send the termination signals to the peers first and then
+wait on them. This is accomplished by the functions
+@code{GNUNET_TESTING_peer_kill()} which sends a termination signal to the
+peer, and the function @code{GNUNET_TESTING_peer_wait()} which waits on
+the peer.
+
+Further finer control can be achieved by choosing to stop a peer
+asynchronously with the function @code{GNUNET_TESTING_peer_stop_async()}.
+This function takes a callback parameter and a closure for it in addition
+to the handle to the peer to stop. The callback function is called with
+the given closure when the peer is stopped. Using this function
+eliminates blocking while waiting for the peer to terminate.
+
+An asynchronous peer stop can be cancelled by calling the function
+@code{GNUNET_TESTING_peer_stop_async_cancel()}. Note that calling this
+function does not prevent the peer from terminating if the termination
+signal has already been sent to it. It does, however, cancels the
+callback to be called when the peer is stopped.
+
+@c ***********************************************************************
+@node Helper functions
+@subsection Helper functions
+
+Most of the testcases can benefit from an abstraction which configures a
+peer and starts it. This is provided by the function
+@code{GNUNET_TESTING_peer_run()}. This function takes the testing
+directory pathname, a configuration template, a callback and its closure.
+This function creates a peer in the given testing directory by using the
+configuration template, starts the peer and calls the given callback with
+the given closure.
+
+The function @code{GNUNET_TESTING_peer_run()} starts the ARM service of
+the peer which starts the rest of the configured services. A similar
+function @code{GNUNET_TESTING_service_run} can be used to just start a
+single service of a peer. In this case, the peer's ARM service is not
+started; instead, only the given service is run.
+
+@c ***********************************************************************
+@node Testing with multiple processes
+@subsection Testing with multiple processes
+
+When testing GNUnet, the splitting of the code into a services and clients
+often complicates testing. The solution to this is to have the testcase
+fork @code{gnunet-service-arm}, ask it to start the required server and
+daemon processes and then execute appropriate client actions (to test the
+client APIs or the core module or both). If necessary, multiple ARM
+services can be forked using different ports (!) to simulate a network.
+However, most of the time only one ARM process is needed. Note that on
+exit, the testcase should shutdown ARM with a @code{TERM} signal (to give
+it the chance to cleanly stop its child processes).
+
+The following code illustrates spawning and killing an ARM process from a
+testcase:
+
+@example
+static void run (void *cls, char *const *args, const char
+*cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg) @{ struct
+GNUNET_OS_Process *arm_pid; arm_pid = GNUNET_OS_start_process (NULL, NULL,
+"gnunet-service-arm", "gnunet-service-arm", "-c", cfgname, NULL);
+ /* do real test work here */
+ if (0 != GNUNET_OS_process_kill (arm_pid, SIGTERM)) GNUNET_log_strerror
+ (GNUNET_ERROR_TYPE_WARNING, "kill"); GNUNET_assert (GNUNET_OK ==
+ GNUNET_OS_process_wait (arm_pid)); GNUNET_OS_process_close (arm_pid); @}
+
+GNUNET_PROGRAM_run (argc, argv, "NAME-OF-TEST", "nohelp", options, &run, cls);
+@end example
+
+
+An alternative way that works well to test plugins is to implement a
+mock-version of the environment that the plugin expects and then to
+simply load the plugin directly.
+
+@c ***********************************************************************
+@node Performance regression analysis with Gauger
+@section Performance regression analysis with Gauger
+
+To help avoid performance regressions, GNUnet uses Gauger. Gauger is a
+simple logging tool that allows remote hosts to send performance data to
+a central server, where this data can be analyzed and visualized. Gauger
+shows graphs of the repository revisions and the performace data recorded
+for each revision, so sudden performance peaks or drops can be identified
+and linked to a specific revision number.
+
+In the case of GNUnet, the buildbots log the performance data obtained
+during the tests after each build. The data can be accesed on GNUnet's
+Gauger page.
+
+The menu on the left allows to select either the results of just one
+build bot (under "Hosts") or review the data from all hosts for a given
+test result (under "Metrics"). In case of very different absolute value
+of the results, for instance arm vs. amd64 machines, the option
+"Normalize" on a metric view can help to get an idea about the
+performance evolution across all hosts.
+
+Using Gauger in GNUnet and having the performance of a module tracked over
+time is very easy. First of course, the testcase must generate some
+consistent metric, which makes sense to have logged. Highly volatile or
+random dependant metrics probably are not ideal candidates for meaningful
+regression detection.
+
+To start logging any value, just include @code{gauger.h} in your testcase
+code. Then, use the macro @code{GAUGER()} to make the buildbots log
+whatever value is of interest for you to @code{gnunet.org}'s Gauger
+server. No setup is necessary as most buildbots have already everything
+in place and new metrics are created on demand. To delete a metric, you
+need to contact a member of the GNUnet development team (a file will need
+to be removed manually from the respective directory).
+
+The code in the test should look like this:
+
+@example
+[other includes]
+#include <gauger.h>
+
+int main (int argc, char *argv[]) @{
+
+ [run test, generate data] GAUGER("YOUR_MODULE", "METRIC_NAME", (float)value,
+ "UNIT"); @}
+@end example
+
+
+Where:
+
+@table @asis
+
+@item @strong{YOUR_MODULE} is a category in the gauger page and should be
+the name of the module or subsystem like "Core" or "DHT"
+@item @strong{METRIC} is
+the name of the metric being collected and should be concise and
+descriptive, like "PUT operations in sqlite-datastore".
+@item @strong{value} is the value
+of the metric that is logged for this run.
+@item @strong{UNIT} is the unit in
+which the value is measured, for instance "kb/s" or "kb of RAM/node".
+@end table
+
+If you wish to use Gauger for your own project, you can grab a copy of the
+latest stable release or check out Gauger's Subversion repository.
+
+@c ***********************************************************************
+@node GNUnet's TESTBED Subsystem
+@section GNUnet's TESTBED Subsystem
+
+The TESTBED subsystem facilitates testing and measuring of multi-peer
+deployments on a single host or over multiple hosts.
+
+The architecture of the testbed module is divided into the following:
+@itemize @bullet
+
+@item Testbed API: An API which is used by the testing driver programs. It
+provides with functions for creating, destroying, starting, stopping
+peers, etc.
+
+@item Testbed service (controller): A service which is started through the
+Testbed API. This service handles operations to create, destroy, start,
+stop peers, connect them, modify their configurations.
+
+@item Testbed helper: When a controller has to be started on a host, the
+testbed API starts the testbed helper on that host which in turn starts
+the controller. The testbed helper receives a configuration for the
+controller through its stdin and changes it to ensure the controller
+doesn't run into any port conflict on that host.
+@end itemize
+
+
+The testbed service (controller) is different from the other GNUnet
+services in that it is not started by ARM and is not supposed to be run
+as a daemon. It is started by the testbed API through a testbed helper.
+In a typical scenario involving multiple hosts, a controller is started
+on each host. Controllers take up the actual task of creating peers,
+starting and stopping them on the hosts they run.
+
+While running deployments on a single localhost the testbed API starts the
+testbed helper directly as a child process. When running deployments on
+remote hosts the testbed API starts Testbed Helpers on each remote host
+through remote shell. By default testbed API uses SSH as a remote shell.
+This can be changed by setting the environmental variable
+GNUNET_TESTBED_RSH_CMD to the required remote shell program. This
+variable can also contain parameters which are to be passed to the remote
+shell program. For e.g:
+
+@example
+export GNUNET_TESTBED_RSH_CMD="ssh -o BatchMode=yes \
+-o NoHostAuthenticationForLocalhost=yes %h"@
+@end example
+
+Substitutions are allowed int the above command string also allows for
+substitions. through placemarks which begin with a `%'. At present the
+following substitutions are supported
+
+@itemize @bullet
+@item
+%h: hostname
+@item
+%u: username
+@item
+%p: port
+@end itemize
+
+Note that the substitution placemark is replaced only when the
+corresponding field is available and only once. Specifying @code{%u@@%h}
+doesn't work either. If you want to user username substitutions for SSH
+use the argument @code{-l} before the username substitution.
+Ex: @code{ssh -l %u -p %p %h}
+
+The testbed API and the helper communicate through the helpers stdin and
+stdout. As the helper is started through a remote shell on remote hosts
+any output messages from the remote shell interfere with the communication
+and results in a failure while starting the helper. For this reason, it is
+suggested to use flags to make the remote shells produce no output
+messages and to have password-less logins. The default remote shell, SSH,
+the default options are:
+
+@example
+-o BatchMode=yes -o NoHostBasedAuthenticationForLocalhost=yes"
+@end example
+
+Password-less logins should be ensured by using SSH keys.
+
+Since the testbed API executes the remote shell as a non-interactive
+shell, certain scripts like .bashrc, .profiler may not be executed. If
+this is the case testbed API can be forced to execute an interactive
+shell by setting up the environmental variable
+`GNUNET_TESTBED_RSH_CMD_SUFFIX' to a shell program.
+An example could be:
+
+@example
+export GNUNET_TESTBED_RSH_CMD_SUFFIX="sh -lc"
+@end example
+
+The testbed API will then execute the remote shell program as:
+
+@example
+$GNUNET_TESTBED_RSH_CMD -p $port $dest $GNUNET_TESTBED_RSH_CMD_SUFFIX \
+gnunet-helper-testbed
+@end example
+
+On some systems, problems may arise while starting testbed helpers if
+GNUnet is installed into a custom location since the helper may not be
+found in the standard path. This can be addressed by setting the variable
+`HELPER_BINARY_PATH' to the path of the testbed helper. Testbed API will
+then use this path to start helper binaries both locally and remotely.
+
+Testbed API can accessed by including "gnunet_testbed_service.h" file and
+linking with -lgnunettestbed.
+
+
+
+@c ***********************************************************************
+@menu
+* Supported Topologies::
+* Hosts file format::
+* Topology file format::
+* Testbed Barriers::
+* Automatic large-scale deployment of GNUnet in the PlanetLab testbed::
+* TESTBED Caveats::
+@end menu
+
+@node Supported Topologies
+@subsection Supported Topologies
+
+While testing multi-peer deployments, it is often needed that the peers
+are connected in some topology. This requirement is addressed by the
+function @code{GNUNET_TESTBED_overlay_connect()} which connects any given
+two peers in the testbed.
+
+The API also provides a helper function
+@code{GNUNET_TESTBED_overlay_configure_topology()} to connect a given set
+of peers in any of the following supported topologies:
+
+@itemize @bullet
+
+@item @code{GNUNET_TESTBED_TOPOLOGY_CLIQUE}: All peers are connected with
+each other
+
+@item @code{GNUNET_TESTBED_TOPOLOGY_LINE}: Peers are connected to form a
+line
+
+@item @code{GNUNET_TESTBED_TOPOLOGY_RING}: Peers are connected to form a
+ring topology
+
+@item @code{GNUNET_TESTBED_TOPOLOGY_2D_TORUS}: Peers are connected to
+form a 2 dimensional torus topology. The number of peers may not be a
+perfect square, in that case the resulting torus may not have the uniform
+poloidal and toroidal lengths
+
+@item @code{GNUNET_TESTBED_TOPOLOGY_ERDOS_RENYI}: Topology is generated
+to form a random graph. The number of links to be present should be given
+
+@item @code{GNUNET_TESTBED_TOPOLOGY_SMALL_WORLD}: Peers are connected to
+form a 2D Torus with some random links among them. The number of random
+links are to be given
+
+@item @code{GNUNET_TESTBED_TOPOLOGY_SMALL_WORLD_RING}: Peers are
+connected to form a ring with some random links among them. The number of
+random links are to be given
+
+@item @code{GNUNET_TESTBED_TOPOLOGY_SCALE_FREE}: Connects peers in a
+topology where peer connectivity follows power law - new peers are
+connected with high probabililty to well connected peers.
+@footnote{See Emergence of Scaling in Random Networks. Science 286,
+509-512, 1999.}
+
+@item @code{GNUNET_TESTBED_TOPOLOGY_FROM_FILE}: The topology information
+is loaded from a file. The path to the file has to be given. See Topology
+file format for the format of this file.
+
+@item @code{GNUNET_TESTBED_TOPOLOGY_NONE}: No topology
+@end itemize
+
+
+The above supported topologies can be specified respectively by setting
+the variable @code{OVERLAY_TOPOLOGY} to the following values in the
+configuration passed to Testbed API functions
+@code{GNUNET_TESTBED_test_run()} and
+@code{GNUNET_TESTBED_run()}:
+@itemize @bullet
+@item @code{CLIQUE}
+@item @code{RING}
+@item @code{LINE}
+@item @code{2D_TORUS}
+@item @code{RANDOM}
+@item @code{SMALL_WORLD}
+@item @code{SMALL_WORLD_RING}
+@item @code{SCALE_FREE}
+@item @code{FROM_FILE}
+@item @code{NONE}
+@end itemize
+
+
+Topologies @code{RANDOM}, @code{SMALL_WORLD} and @code{SMALL_WORLD_RING}
+require the option @code{OVERLAY_RANDOM_LINKS} to be set to the number of
+random links to be generated in the configuration. The option will be
+ignored for the rest of the topologies.
+
+Topology @code{SCALE_FREE} requires the options
+@code{SCALE_FREE_TOPOLOGY_CAP} to be set to the maximum number of peers
+which can connect to a peer and @code{SCALE_FREE_TOPOLOGY_M} to be set to
+how many peers a peer should be atleast connected to.
+
+Similarly, the topology @code{FROM_FILE} requires the option
+@code{OVERLAY_TOPOLOGY_FILE} to contain the path of the file containing
+the topology information. This option is ignored for the rest of the
+topologies. See Topology file format for the format of this file.
+
+@c ***********************************************************************
+@node Hosts file format
+@subsection Hosts file format
+
+The testbed API offers the function GNUNET_TESTBED_hosts_load_from_file()
+to load from a given file details about the hosts which testbed can use
+for deploying peers. This function is useful to keep the data about hosts
+separate instead of hard coding them in code.
+
+Another helper function from testbed API, GNUNET_TESTBED_run() also takes
+a hosts file name as its parameter. It uses the above function to
+populate the hosts data structures and start controllers to deploy peers.
+
+These functions require the hosts file to be of the following format:
+@itemize @bullet
+@item Each line is interpreted to have details about a host
+@item Host details should include the username to use for logging into the
+host, the hostname of the host and the port number to use for the remote
+shell program. All thee values should be given.
+@item These details should be given in the following format:
+@code{<username>@@<hostname>:<port>}
+@end itemize
+
+Note that having canonical hostnames may cause problems while resolving
+the IP addresses (See this bug). Hence it is advised to provide the hosts'
+IP numerical addresses as hostnames whenever possible.
+
+@c ***********************************************************************
+@node Topology file format
+@subsection Topology file format
+
+A topology file describes how peers are to be connected. It should adhere
+to the following format for testbed to parse it correctly.
+
+Each line should begin with the target peer id. This should be followed by
+a colon(`:') and origin peer ids seperated by `|'. All spaces except for
+newline characters are ignored. The API will then try to connect each
+origin peer to the target peer.
+
+For example, the following file will result in 5 overlay connections:
+[2->1], [3->1],[4->3], [0->3], [2->0]@ @code{@ 1:2|3@ 3:4| 0@ 0: 2@ }
+
+@c ***********************************************************************
+@node Testbed Barriers
+@subsection Testbed Barriers
+
+The testbed subsystem's barriers API facilitates coordination among the
+peers run by the testbed and the experiment driver. The concept is
+similar to the barrier synchronisation mechanism found in parallel
+programming or multi-threading paradigms - a peer waits at a barrier upon
+reaching it until the barrier is reached by a predefined number of peers.
+This predefined number of peers required to cross a barrier is also called
+quorum. We say a peer has reached a barrier if the peer is waiting for the
+barrier to be crossed. Similarly a barrier is said to be reached if the
+required quorum of peers reach the barrier. A barrier which is reached is
+deemed as crossed after all the peers waiting on it are notified.
+
+The barriers API provides the following functions:
+@itemize @bullet
+@item @strong{@code{GNUNET_TESTBED_barrier_init()}:} function to
+initialse a barrier in the experiment
+@item @strong{@code{GNUNET_TESTBED_barrier_cancel()}:} function to cancel
+a barrier which has been initialised before
+@item @strong{@code{GNUNET_TESTBED_barrier_wait()}:} function to signal
+barrier service that the caller has reached a barrier and is waiting for
+it to be crossed
+@item @strong{@code{GNUNET_TESTBED_barrier_wait_cancel()}:} function to
+stop waiting for a barrier to be crossed
+@end itemize
+
+
+Among the above functions, the first two, namely
+@code{GNUNET_TESTBED_barrier_init()} and
+@code{GNUNET_TESTBED_barrier_cancel()} are used by experiment drivers. All
+barriers should be initialised by the experiment driver by calling
+@code{GNUNET_TESTBED_barrier_init()}. This function takes a name to
+identify the barrier, the quorum required for the barrier to be crossed
+and a notification callback for notifying the experiment driver when the
+barrier is crossed. @code{GNUNET_TESTBED_barrier_cancel()} cancels an
+initialised barrier and frees the resources allocated for it. This
+function can be called upon a initialised barrier before it is crossed.
+
+The remaining two functions @code{GNUNET_TESTBED_barrier_wait()} and
+@code{GNUNET_TESTBED_barrier_wait_cancel()} are used in the peer's
+processes. @code{GNUNET_TESTBED_barrier_wait()} connects to the local
+barrier service running on the same host the peer is running on and
+registers that the caller has reached the barrier and is waiting for the
+barrier to be crossed. Note that this function can only be used by peers
+which are started by testbed as this function tries to access the local
+barrier service which is part of the testbed controller service. Calling
+@code{GNUNET_TESTBED_barrier_wait()} on an uninitialised barrier results
+in failure. @code{GNUNET_TESTBED_barrier_wait_cancel()} cancels the
+notification registered by @code{GNUNET_TESTBED_barrier_wait()}.
+
+
+@c ***********************************************************************
+@menu
+* Implementation::
+@end menu
+
+@node Implementation
+@subsubsection Implementation
+
+Since barriers involve coordination between experiment driver and peers,
+the barrier service in the testbed controller is split into two
+components. The first component responds to the message generated by the
+barrier API used by the experiment driver (functions
+@code{GNUNET_TESTBED_barrier_init()} and
+@code{GNUNET_TESTBED_barrier_cancel()}) and the second component to the
+messages generated by barrier API used by peers (functions
+@code{GNUNET_TESTBED_barrier_wait()} and
+@code{GNUNET_TESTBED_barrier_wait_cancel()}).
+
+Calling @code{GNUNET_TESTBED_barrier_init()} sends a
+@code{GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_INIT} message to the master
+controller. The master controller then registers a barrier and calls
+@code{GNUNET_TESTBED_barrier_init()} for each its subcontrollers. In this
+way barrier initialisation is propagated to the controller hierarchy.
+While propagating initialisation, any errors at a subcontroller such as
+timeout during further propagation are reported up the hierarchy back to
+the experiment driver.
+
+Similar to @code{GNUNET_TESTBED_barrier_init()},
+@code{GNUNET_TESTBED_barrier_cancel()} propagates
+@code{GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_CANCEL} message which causes
+controllers to remove an initialised barrier.
+
+The second component is implemented as a separate service in the binary
+`gnunet-service-testbed' which already has the testbed controller service.
+Although this deviates from the gnunet process architecture of having one
+service per binary, it is needed in this case as this component needs
+access to barrier data created by the first component. This component
+responds to @code{GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_WAIT} messages from
+local peers when they call @code{GNUNET_TESTBED_barrier_wait()}. Upon
+receiving @code{GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_WAIT} message, the
+service checks if the requested barrier has been initialised before and
+if it was not initialised, an error status is sent through
+@code{GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS} message to the local
+peer and the connection from the peer is terminated. If the barrier is
+initialised before, the barrier's counter for reached peers is incremented
+and a notification is registered to notify the peer when the barrier is
+reached. The connection from the peer is left open.
+
+When enough peers required to attain the quorum send
+@code{GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_WAIT} messages, the controller
+sends a @code{GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS} message to its
+parent informing that the barrier is crossed. If the controller has
+started further subcontrollers, it delays this message until it receives
+a similar notification from each of those subcontrollers. Finally, the
+barriers API at the experiment driver receives the
+@code{GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS} when the barrier is
+reached at all the controllers.
+
+The barriers API at the experiment driver responds to the
+@code{GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS} message by echoing it
+back to the master controller and notifying the experiment controller
+through the notification callback that a barrier has been crossed. The
+echoed @code{GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS} message is
+propagated by the master controller to the controller hierarchy. This
+propagation triggers the notifications registered by peers at each of the
+controllers in the hierarchy. Note the difference between this downward
+propagation of the @code{GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS}
+message from its upward propagation --- the upward propagation is needed
+for ensuring that the barrier is reached by all the controllers and the
+downward propagation is for triggering that the barrier is crossed.
+
+@c ***********************************************************************
+@node Automatic large-scale deployment of GNUnet in the PlanetLab testbed
+@subsection Automatic large-scale deployment of GNUnet in the PlanetLab testbed
+
+PlanetLab is as a testbed for computer networking and distributed systems
+research. It was established in 2002 and as of June 2010 was composed of
+1090 nodes at 507 sites worldwide.
+
+To automate the GNUnet we created a set of automation tools to simplify
+the large-scale deployment. We provide you a set of scripts you can use
+to deploy GNUnet on a set of nodes and manage your installation.
+
+Please also check @uref{https://gnunet.org/installation-fedora8-svn} and
+@uref{https://gnunet.org/installation-fedora12-svn} to find detailled
+instructions how to install GNUnet on a PlanetLab node.
+
+
+@c ***********************************************************************
+@menu
+* PlanetLab Automation for Fedora8 nodes::
+* Install buildslave on PlanetLab nodes running fedora core 8::
+* Setup a new PlanetLab testbed using GPLMT::
+* Why do i get an ssh error when using the regex profiler?::
+@end menu
+
+@node PlanetLab Automation for Fedora8 nodes
+@subsubsection PlanetLab Automation for Fedora8 nodes
+
+@c ***********************************************************************
+@node Install buildslave on PlanetLab nodes running fedora core 8
+@subsubsection Install buildslave on PlanetLab nodes running fedora core 8
+@c ** Actually this is a subsubsubsection, but must be fixed differently
+@c ** as subsubsection is the lowest.
+
+Since most of the PlanetLab nodes are running the very old fedora core 8
+image, installing the buildslave software is quite some pain. For our
+PlanetLab testbed we figured out how to install the buildslave software
+best.
+
+@c This is a vvery terrible way to suggest installing software.
+@c FIXME: Is there an official, safer way instead of blind-piping a
+@c script?
+@c FIXME: Use newer pypi URLs below.
+Install Distribute for python:@ @code{@ curl
+http://python-distribute.org/distribute_setup.py | sudo python@ }
+
+Install Distribute for zope.interface <= 3.8.0 (4.0 and 4.0.1 will not
+work):
+
+@example
+wget https://pypi.python.org/packages/source/z/zope.interface/zope.interface-3.8.0.tar.gz
+tar zvfz zope.interface-3.8.0.tar.gz@ cd zope.interface-3.8.0
+sudo python setup.py install
+@end example
+
+Install the buildslave software (0.8.6 was the latest version):
+
+@example
+wget http://buildbot.googlecode.com/files/buildbot-slave-0.8.6p1.tar.gz
+tar xvfz buildbot-slave-0.8.6p1.tar.gz@ cd buildslave-0.8.6p1
+sudo python setup.py install
+@end example
+
+The setup will download the matching twisted package and install it.
+It will also try to install the latest version of zope.interface which
+will fail to install. Buildslave will work anyway since version 3.8.0
+was installed before!
+
+@c ***********************************************************************
+@node Setup a new PlanetLab testbed using GPLMT
+@subsubsection Setup a new PlanetLab testbed using GPLMT
+
+@itemize @bullet
+@item Get a new slice and assign nodes
+Ask your PlanetLab PI to give you a new slice and assign the nodes you
+need
+@item Install a buildmaster
+You can stick to the buildbot documentation:@
+@uref{http://buildbot.net/buildbot/docs/current/manual/installation.html}
+@item Install the buildslave software on all nodes
+To install the buildslave on all nodes assigned to your slice you can use
+the tasklist @code{install_buildslave_fc8.xml} provided with GPLMT:
+
+@example
+./gplmt.py -c contrib/tumple_gnunet.conf -t \
+contrib/tasklists/install_buildslave_fc8.xml -a -p <planetlab password>
+@end example
+
+@item Create the buildmaster configuration and the slave setup commands
+
+The master and the and the slaves have need to have credentials and the
+master has to have all nodes configured. This can be done with the
+@code{create_buildbot_configuration.py} script in the @code{scripts}
+directory
+
+This scripts takes a list of nodes retrieved directly from PlanetLab or
+read from a file and a configuration template and creates:
+
+@itemize @bullet
+@item a tasklist which can be executed with gplmt to setup the slaves
+@item a master.cfg file containing a PlanetLab nodes
+@end itemize
+
+A configuration template is included in the <contrib>, most important is
+that the script replaces the following tags in the template:
+
+%GPLMT_BUILDER_DEFINITION :@ GPLMT_BUILDER_SUMMARY@ GPLMT_SLAVES@
+%GPLMT_SCHEDULER_BUILDERS
+
+Create configuration for all nodes assigned to a slice:@ @code{@
+./create_buildbot_configuration.py -u <planetlab username> -p <planetlab
+password> -s <slice> -m <buildmaster+port> -t <template>@ }@ Create
+configuration for some nodes in a file:@ @code{@
+./create_buildbot_configuration.p -f <node_file> -m <buildmaster+port> -t
+<template>@ }
+
+@item Copy the @code{master.cfg} to the buildmaster and start it
+Use @code{buildbot start <basedir>} to start the server
+@item Setup the buildslaves
+@end itemize
+
+@c ***********************************************************************
+@node Why do i get an ssh error when using the regex profiler?
+@subsubsection Why do i get an ssh error when using the regex profiler?
+
+Why do i get an ssh error "Permission denied (publickey,password)." when
+using the regex profiler although passwordless ssh to localhost works
+using publickey and ssh-agent?
+
+You have to generate a public/private-key pair with no password:@
+@code{ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_localhost}@
+and then add the following to your ~/.ssh/config file:
+
+@code{Host 127.0.0.1@ IdentityFile ~/.ssh/id_localhost}
+
+now make sure your hostsfile looks like@
+
+[USERNAME]@@127.0.0.1:22@
+[USERNAME]@@127.0.0.1:22
+
+You can test your setup by running `ssh 127.0.0.1` in a terminal and then
+in the opened session run it again. If you were not asked for a password
+on either login, then you should be good to go.
+
+@c ***********************************************************************
+@node TESTBED Caveats
+@subsection TESTBED Caveats
+
+This section documents a few caveats when using the GNUnet testbed
+subsystem.
+
+
+@c ***********************************************************************
+@menu
+* CORE must be started::
+* ATS must want the connections::
+@end menu
+
+@node CORE must be started
+@subsubsection CORE must be started
+
+A simple issue is #3993: Your configuration MUST somehow ensure that for
+each peer the CORE service is started when the peer is setup, otherwise
+TESTBED may fail to connect peers when the topology is initialized, as
+TESTBED will start some CORE services but not necessarily all (but it
+relies on all of them running). The easiest way is to set
+'FORCESTART = YES' in the '[core]' section of the configuration file.
+Alternatively, having any service that directly or indirectly depends on
+CORE being started with FORCESTART will also do. This issue largely arises
+if users try to over-optimize by not starting any services with
+FORCESTART.
+
+@c ***********************************************************************
+@node ATS must want the connections
+@subsubsection ATS must want the connections
+
+When TESTBED sets up connections, it only offers the respective HELLO
+information to the TRANSPORT service. It is then up to the ATS service to
+@strong{decide} to use the connection. The ATS service will typically
+eagerly establish any connection if the number of total connections is
+low (relative to bandwidth). Details may further depend on the
+specific ATS backend that was configured. If ATS decides to NOT establish
+a connection (even though TESTBED provided the required information), then
+that connection will count as failed for TESTBED. Note that you can
+configure TESTBED to tolerate a certain number of connection failures
+(see '-e' option of gnunet-testbed-profiler). This issue largely arises
+for dense overlay topologies, especially if you try to create cliques
+with more than 20 peers.
+
+@c ***********************************************************************
+@node libgnunetutil
+@section libgnunetutil
+
+libgnunetutil is the fundamental library that all GNUnet code builds upon.
+Ideally, this library should contain most of the platform dependent code
+(except for user interfaces and really special needs that only few
+applications have). It is also supposed to offer basic services that most
+if not all GNUnet binaries require. The code of libgnunetutil is in the
+@file{src/util/} directory. The public interface to the library is in the
+gnunet_util.h header. The functions provided by libgnunetutil fall
+roughly into the following categories (in roughly the order of importance
+for new developers):
+
+@itemize @bullet
+@item logging (common_logging.c)
+@item memory allocation (common_allocation.c)
+@item endianess conversion (common_endian.c)
+@item internationalization (common_gettext.c)
+@item String manipulation (string.c)
+@item file access (disk.c)
+@item buffered disk IO (bio.c)
+@item time manipulation (time.c)
+@item configuration parsing (configuration.c)
+@item command-line handling (getopt*.c)
+@item cryptography (crypto_*.c)
+@item data structures (container_*.c)
+@item CPS-style scheduling (scheduler.c)
+@item Program initialization (program.c)
+@item Networking (network.c, client.c, server*.c, service.c)
+@item message queueing (mq.c)
+@item bandwidth calculations (bandwidth.c)
+@item Other OS-related (os*.c, plugin.c, signal.c)
+@item Pseudonym management (pseudonym.c)
+@end itemize
+
+It should be noted that only developers that fully understand this entire
+API will be able to write good GNUnet code.
+
+Ideally, porting GNUnet should only require porting the gnunetutil
+library. More testcases for the gnunetutil APIs are therefore a great
+way to make porting of GNUnet easier.
+
+@menu
+* Logging::
+* Interprocess communication API (IPC)::
+* Cryptography API::
+* Message Queue API::
+* Service API::
+* Optimizing Memory Consumption of GNUnet's (Multi-) Hash Maps::
+* The CONTAINER_MDLL API::
+@end menu
+
+@c ***********************************************************************
+@node Logging
+@subsection Logging
+
+GNUnet is able to log its activity, mostly for the purposes of debugging
+the program at various levels.
+
+@file{gnunet_common.h} defines several @strong{log levels}:
+@table @asis
+
+@item ERROR for errors (really problematic situations, often leading to
+crashes)
+@item WARNING for warnings (troubling situations that might have
+negative consequences, although not fatal)
+@item INFO for various information.
+Used somewhat rarely, as GNUnet statistics is used to hold and display
+most of the information that users might find interesting.
+@item DEBUG for debugging.
+Does not produce much output on normal builds, but when extra logging is
+enabled at compile time, a staggering amount of data is outputted under
+this log level.
+@end table
+
+
+Normal builds of GNUnet (configured with @code{--enable-logging[=yes]})
+are supposed to log nothing under DEBUG level. The
+@code{--enable-logging=verbose} configure option can be used to create a
+build with all logging enabled. However, such build will produce large
+amounts of log data, which is inconvenient when one tries to hunt down a
+specific problem.
+
+To mitigate this problem, GNUnet provides facilities to apply a filter to
+reduce the logs:
+@table @asis
+
+@item Logging by default When no log levels are configured in any other
+way (see below), GNUnet will default to the WARNING log level. This
+mostly applies to GNUnet command line utilities, services and daemons;
+tests will always set log level to WARNING or, if
+@code{--enable-logging=verbose} was passed to configure, to DEBUG. The
+default level is suggested for normal operation.
+@item The -L option Most GNUnet executables accept an "-L loglevel" or
+"--log=loglevel" option. If used, it makes the process set a global log
+level to "loglevel". Thus it is possible to run some processes
+with -L DEBUG, for example, and others with -L ERROR to enable specific
+settings to diagnose problems with a particular process.
+@item Configuration files. Because GNUnet
+service and deamon processes are usually launched by gnunet-arm, it is not
+possible to pass different custom command line options directly to every
+one of them. The options passed to @code{gnunet-arm} only affect
+gnunet-arm and not the rest of GNUnet. However, one can specify a
+configuration key "OPTIONS" in the section that corresponds to a service
+or a daemon, and put a value of "-L loglevel" there. This will make the
+respective service or daemon set its log level to "loglevel" (as the
+value of OPTIONS will be passed as a command-line argument).
+
+To specify the same log level for all services without creating separate
+"OPTIONS" entries in the configuration for each one, the user can specify
+a config key "GLOBAL_POSTFIX" in the [arm] section of the configuration
+file. The value of GLOBAL_POSTFIX will be appended to all command lines
+used by the ARM service to run other services. It can contain any option
+valid for all GNUnet commands, thus in particular the "-L loglevel"
+option. The ARM service itself is, however, unaffected by GLOBAL_POSTFIX;
+to set log level for it, one has to specify "OPTIONS" key in the [arm]
+section.
+@item Environment variables.
+Setting global per-process log levels with "-L loglevel" does not offer
+sufficient log filtering granularity, as one service will call interface
+libraries and supporting libraries of other GNUnet services, potentially
+producing lots of debug log messages from these libraries. Also, changing
+the config file is not always convenient (especially when running the
+GNUnet test suite).@ To fix that, and to allow GNUnet to use different
+log filtering at runtime without re-compiling the whole source tree, the
+log calls were changed to be configurable at run time. To configure them
+one has to define environment variables "GNUNET_FORCE_LOGFILE",
+"GNUNET_LOG" and/or "GNUNET_FORCE_LOG":
+@itemize @bullet
+
+@item "GNUNET_LOG" only affects the logging when no global log level is
+configured by any other means (that is, the process does not explicitly
+set its own log level, there are no "-L loglevel" options on command line
+or in configuration files), and can be used to override the default
+WARNING log level.
+
+@item "GNUNET_FORCE_LOG" will completely override any other log
+configuration options given.
+
+@item "GNUNET_FORCE_LOGFILE" will completely override the location of the
+file to log messages to. It should contain a relative or absolute file
+name. Setting GNUNET_FORCE_LOGFILE is equivalent to passing
+"--log-file=logfile" or "-l logfile" option (see below). It supports "[]"
+format in file names, but not "@{@}" (see below).
+@end itemize
+
+
+Because environment variables are inherited by child processes when they
+are launched, starting or re-starting the ARM service with these
+variables will propagate them to all other services.
+
+"GNUNET_LOG" and "GNUNET_FORCE_LOG" variables must contain a specially
+formatted @strong{logging definition} string, which looks like this:@
+
+@example
+[component];[file];[function];[from_line[-to_line]];loglevel[/component...]
+@end example
+
+That is, a logging definition consists of definition entries, separated by
+slashes ('/'). If only one entry is present, there is no need to add a
+slash to its end (although it is not forbidden either).@ All definition
+fields (component, file, function, lines and loglevel) are mandatory, but
+(except for the loglevel) they can be empty. An empty field means
+"match anything". Note that even if fields are empty, the semicolon (';')
+separators must be present.@ The loglevel field is mandatory, and must
+contain one of the log level names (ERROR, WARNING, INFO or DEBUG).@
+The lines field might contain one non-negative number, in which case it
+matches only one line, or a range "from_line-to_line", in which case it
+matches any line in the interval [from_line;to_line] (that is, including
+both start and end line).@ GNUnet mostly defaults component name to the
+name of the service that is implemented in a process ('transport',
+'core', 'peerinfo', etc), but logging calls can specify custom component
+names using @code{GNUNET_log_from}.@ File name and function name are
+provided by the compiler (__FILE__ and __FUNCTION__ built-ins).
+
+Component, file and function fields are interpreted as non-extended
+regular expressions (GNU libc regex functions are used). Matching is
+case-sensitive, "^" and "$" will match the beginning and the end of the
+text. If a field is empty, its contents are automatically replaced with
+a ".*" regular expression, which matches anything. Matching is done in
+the default way, which means that the expression matches as long as it's
+contained anywhere in the string. Thus "GNUNET_" will match both
+"GNUNET_foo" and "BAR_GNUNET_BAZ". Use '^' and/or '$' to make sure that
+the expression matches at the start and/or at the end of the string.
+The semicolon (';') can't be escaped, and GNUnet will not use it in
+component names (it can't be used in function names and file names
+anyway).
+
+@end table
+
+
+Every logging call in GNUnet code will be (at run time) matched against
+the log definitions passed to the process. If a log definition fields are
+matching the call arguments, then the call log level is compared the the
+log level of that definition. If the call log level is less or equal to
+the definition log level, the call is allowed to proceed. Otherwise the
+logging call is forbidden, and nothing is logged. If no definitions
+matched at all, GNUnet will use the global log level or (if a global log
+level is not specified) will default to WARNING (that is, it will allow
+the call to proceed, if its level is less or equal to the global log
+level or to WARNING).
+
+That is, definitions are evaluated from left to right, and the first
+matching definition is used to allow or deny the logging call. Thus it is
+advised to place narrow definitions at the beginning of the logdef
+string, and generic definitions - at the end.
+
+Whether a call is allowed or not is only decided the first time this
+particular call is made. The evaluation result is then cached, so that
+any attempts to make the same call later will be allowed or disallowed
+right away. Because of that runtime log level evaluation should not
+significantly affect the process performance.
+Log definition parsing is only done once, at the first call to
+GNUNET_log_setup () made by the process (which is usually done soon after
+it starts).
+
+At the moment of writing there is no way to specify logging definitions
+from configuration files, only via environment variables.
+
+At the moment GNUnet will stop processing a log definition when it
+encounters an error in definition formatting or an error in regular
+expression syntax, and will not report the failure in any way.
+
+
+@c ***********************************************************************
+@menu
+* Examples::
+* Log files::
+* Updated behavior of GNUNET_log::
+@end menu
+
+@node Examples
+@subsubsection Examples
+
+@table @asis
+
+@item @code{GNUNET_FORCE_LOG=";;;;DEBUG" gnunet-arm -s} Start GNUnet
+process tree, running all processes with DEBUG level (one should be
+careful with it, as log files will grow at alarming rate!)
+@item @code{GNUNET_FORCE_LOG="core;;;;DEBUG" gnunet-arm -s} Start GNUnet
+process tree, running the core service under DEBUG level (everything else
+will use configured or default level).
+
+@item Start GNUnet process tree, allowing any logging calls from
+gnunet-service-transport_validation.c (everything else will use
+configured or default level).
+
+@example
+GNUNET_FORCE_LOG=";gnunet-service-transport_validation.c;;; DEBUG" \
+gnunet-arm -s
+@end example
+
+@item Start GNUnet process tree, allowing any logging calls from
+gnunet-gnunet-service-fs_push.c (everything else will use configured or
+default level).
+
+@example
+GNUNET_FORCE_LOG="fs;gnunet-service-fs_push.c;;;DEBUG" gnunet-arm -s
+@end example
+
+@item Start GNUnet process tree, allowing any logging calls from the
+GNUNET_NETWORK_socket_select function (everything else will use
+configured or default level).
+
+@example
+GNUNET_FORCE_LOG=";;GNUNET_NETWORK_socket_select;;DEBUG" gnunet-arm -s
+@end example
+
+@item Start GNUnet process tree, allowing any logging calls from the
+components that have "transport" in their names, and are made from
+function that have "send" in their names. Everything else will be allowed
+to be logged only if it has WARNING level.
+
+@example
+GNUNET_FORCE_LOG="transport.*;;.*send.*;;DEBUG/;;;;WARNING" gnunet-arm -s
+@end example
+
+@end table
+
+
+On Windows, one can use batch files to run GNUnet processes with special
+environment variables, without affecting the whole system. Such batch
+file will look like this:
+
+@example
+set GNUNET_FORCE_LOG=;;do_transmit;;DEBUG@ gnunet-arm -s
+@end example
+
+(note the absence of double quotes in the environment variable definition,
+as opposed to earlier examples, which use the shell).
+Another limitation, on Windows, GNUNET_FORCE_LOGFILE @strong{MUST} be set
+in order to GNUNET_FORCE_LOG to work.
+
+
+@c ***********************************************************************
+@node Log files
+@subsubsection Log files
+
+GNUnet can be told to log everything into a file instead of stderr (which
+is the default) using the "--log-file=logfile" or "-l logfile" option.
+This option can also be passed via command line, or from the "OPTION" and
+"GLOBAL_POSTFIX" configuration keys (see above). The file name passed
+with this option is subject to GNUnet filename expansion. If specified in
+"GLOBAL_POSTFIX", it is also subject to ARM service filename expansion,
+in particular, it may contain "@{@}" (left and right curly brace)
+sequence, which will be replaced by ARM with the name of the service.
+This is used to keep logs from more than one service separate, while only
+specifying one template containing "@{@}" in GLOBAL_POSTFIX.
+
+As part of a secondary file name expansion, the first occurrence of "[]"
+sequence ("left square brace" followed by "right square brace") in the
+file name will be replaced with a process identifier or the process when
+it initializes its logging subsystem. As a result, all processes will log
+into different files. This is convenient for isolating messages of a
+particular process, and prevents I/O races when multiple processes try to
+write into the file at the same time. This expansion is done
+independently of "@{@}" expansion that ARM service does (see above).
+
+The log file name that is specified via "-l" can contain format characters
+from the 'strftime' function family. For example, "%Y" will be replaced
+with the current year. Using "basename-%Y-%m-%d.log" would include the
+current year, month and day in the log file. If a GNUnet process runs for
+long enough to need more than one log file, it will eventually clean up
+old log files. Currently, only the last three log files (plus the current
+log file) are preserved. So once the fifth log file goes into use (so
+after 4 days if you use "%Y-%m-%d" as above), the first log file will be
+automatically deleted. Note that if your log file name only contains "%Y",
+then log files would be kept for 4 years and the logs from the first year
+would be deleted once year 5 begins. If you do not use any date-related
+string format codes, logs would never be automatically deleted by GNUnet.
+
+
+@c ***********************************************************************
+
+@node Updated behavior of GNUNET_log
+@subsubsection Updated behavior of GNUNET_log
+
+It's currently quite common to see constructions like this all over the
+code:
+
+@example
+#if MESH_DEBUG
+GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: client disconnected\n");
+#endif
+@end example
+
+The reason for the #if is not to avoid displaying the message when
+disabled (GNUNET_ERROR_TYPE takes care of that), but to avoid the
+compiler including it in the binary at all, when compiling GNUnet for
+platforms with restricted storage space / memory (MIPS routers,
+ARM plug computers / dev boards, etc).
+
+This presents several problems: the code gets ugly, hard to write and it
+is very easy to forget to include the #if guards, creating non-consistent
+code. A new change in GNUNET_log aims to solve these problems.
+
+@strong{This change requires to @file{./configure} with at least
+@code{--enable-logging=verbose} to see debug messages.}
+
+Here is an example of code with dense debug statements:
+
+@example
+switch (restrict_topology) @{
+case GNUNET_TESTING_TOPOLOGY_CLIQUE:#if VERBOSE_TESTING
+GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Blacklisting all but clique
+topology\n")); #endif unblacklisted_connections = create_clique (pg,
+&remove_connections, BLACKLIST, GNUNET_NO); break; case
+GNUNET_TESTING_TOPOLOGY_SMALL_WORLD_RING: #if VERBOSE_TESTING GNUNET_log
+(GNUNET_ERROR_TYPE_DEBUG, _("Blacklisting all but small world (ring)
+topology\n")); #endif unblacklisted_connections = create_small_world_ring
+(pg,&remove_connections, BLACKLIST); break;
+@end example
+
+
+Pretty hard to follow, huh?
+
+From now on, it is not necessary to include the #if / #endif statements to
+achieve the same behavior. The GNUNET_log and GNUNET_log_from macros take
+care of it for you, depending on the configure option:
+
+@itemize @bullet
+@item If @code{--enable-logging} is set to @code{no}, the binary will
+contain no log messages at all.
+@item If @code{--enable-logging} is set to @code{yes}, the binary will
+contain no DEBUG messages, and therefore running with -L DEBUG will have
+no effect. Other messages (ERROR, WARNING, INFO, etc) will be included.
+@item If @code{--enable-logging} is set to @code{verbose}, or
+@code{veryverbose} the binary will contain DEBUG messages (still, it will
+be neccessary to run with -L DEBUG or set the DEBUG config option to show
+them).
+@end itemize
+
+
+If you are a developer:
+@itemize @bullet
+@item please make sure that you @code{./configure
+--enable-logging=@{verbose,veryverbose@}}, so you can see DEBUG messages.
+@item please remove the @code{#if} statements around @code{GNUNET_log
+(GNUNET_ERROR_TYPE_DEBUG, ...)} lines, to improve the readibility of your
+code.
+@end itemize
+
+Since now activating DEBUG automatically makes it VERBOSE and activates
+@strong{all} debug messages by default, you probably want to use the
+https://gnunet.org/logging functionality to filter only relevant messages.
+A suitable configuration could be:
+
+@example
+$ export GNUNET_FORCE_LOG="^YOUR_SUBSYSTEM$;;;;DEBUG/;;;;WARNING"
+@end example
+
+Which will behave almost like enabling DEBUG in that subsytem before the
+change. Of course you can adapt it to your particular needs, this is only
+a quick example.
+
+@c ***********************************************************************
+@node Interprocess communication API (IPC)
+@subsection Interprocess communication API (IPC)
+
+In GNUnet a variety of new message types might be defined and used in
+interprocess communication, in this tutorial we use the
+@code{struct AddressLookupMessage} as a example to introduce how to
+construct our own message type in GNUnet and how to implement the message
+communication between service and client.
+(Here, a client uses the @code{struct AddressLookupMessage} as a request
+to ask the server to return the address of any other peer connecting to
+the service.)
+
+
+@c ***********************************************************************
+@menu
+* Define new message types::
+* Define message struct::
+* Client - Establish connection::
+* Client - Initialize request message::
+* Client - Send request and receive response::
+* Server - Startup service::
+* Server - Add new handles for specified messages::
+* Server - Process request message::
+* Server - Response to client::
+* Server - Notification of clients::
+* Conversion between Network Byte Order (Big Endian) and Host Byte Order::
+@end menu
+
+@node Define new message types
+@subsubsection Define new message types
+
+First of all, you should define the new message type in
+@file{gnunet_protocols.h}:
+
+@example
+ // Request to look addresses of peers in server.
+#define GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_LOOKUP 29
+ // Response to the address lookup request.
+#define GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_REPLY 30
+@end example
+
+@c ***********************************************************************
+@node Define message struct
+@subsubsection Define message struct
+
+After the type definition, the specified message structure should also be
+described in the header file, e.g. transport.h in our case.
+@example
+GNUNET_NETWORK_STRUCT_BEGIN
+
+struct AddressLookupMessage @{ struct GNUNET_MessageHeader header; int32_t
+numeric_only GNUNET_PACKED; struct GNUNET_TIME_AbsoluteNBO timeout; uint32_t
+addrlen GNUNET_PACKED;
+ /* followed by 'addrlen' bytes of the actual address, then
+ followed by the 0-terminated name of the transport */ @};
+ GNUNET_NETWORK_STRUCT_END
+@end example
+
+
+Please note @code{GNUNET_NETWORK_STRUCT_BEGIN} and @code{GNUNET_PACKED}
+which both ensure correct alignment when sending structs over the network.
+
+@menu
+@end menu
+
+@c ***********************************************************************
+@node Client - Establish connection
+@subsubsection Client - Establish connection
+@c %**end of header
+
+
+At first, on the client side, the underlying API is employed to create a
+new connection to a service, in our example the transport service would be
+connected.
+
+@example
+struct GNUNET_CLIENT_Connection *client; client =
+GNUNET_CLIENT_connect ("transport", cfg);
+@end example
+
+@c ***********************************************************************
+@node Client - Initialize request message
+@subsubsection Client - Initialize request message
+@c %**end of header
+
+When the connection is ready, we initialize the message. In this step,
+all the fields of the message should be properly initialized, namely the
+size, type, and some extra user-defined data, such as timeout, name of
+transport, address and name of transport.
+
+@example
+struct AddressLookupMessage *msg; size_t len =
+sizeof (struct AddressLookupMessage) + addressLen + strlen (nameTrans) + 1;
+msg->header->size = htons (len); msg->header->type = htons
+(GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_LOOKUP); msg->timeout =
+GNUNET_TIME_absolute_hton (abs_timeout); msg->addrlen = htonl (addressLen);
+char *addrbuf = (char *) &msg[1]; memcpy (addrbuf, address, addressLen); char
+*tbuf = &addrbuf[addressLen]; memcpy (tbuf, nameTrans, strlen (nameTrans) + 1);
+@end example
+
+Note that, here the functions @code{htonl}, @code{htons} and
+@code{GNUNET_TIME_absolute_hton} are applied to convert little endian
+into big endian, about the usage of the big/small edian order and the
+corresponding conversion function please refer to Introduction of
+Big Endian and Little Endian.
+
+@c ***********************************************************************
+@node Client - Send request and receive response
+@subsubsection Client - Send request and receive response
+@c %**end of header
+
+@b{FIXME: This is very outdated, see the tutorial for the current API!}
+
+Next, the client would send the constructed message as a request to the
+service and wait for the response from the service. To accomplish this
+goal, there are a number of API calls that can be used. In this example,
+@code{GNUNET_CLIENT_transmit_and_get_response} is chosen as the most
+appropriate function to use.
+
+@example
+GNUNET_CLIENT_transmit_and_get_response
+(client, msg->header, timeout, GNUNET_YES, &address_response_processor,
+arp_ctx);
+@end example
+
+the argument @code{address_response_processor} is a function with
+@code{GNUNET_CLIENT_MessageHandler} type, which is used to process the
+reply message from the service.
+
+@node Server - Startup service
+@subsubsection Server - Startup service
+
+After receiving the request message, we run a standard GNUnet service
+startup sequence using @code{GNUNET_SERVICE_run}, as follows,
+
+@example
+int main(int
+argc, char**argv) @{ GNUNET_SERVICE_run(argc, argv, "transport"
+GNUNET_SERVICE_OPTION_NONE, &run, NULL)); @}
+@end example
+
+@c ***********************************************************************
+@node Server - Add new handles for specified messages
+@subsubsection Server - Add new handles for specified messages
+@c %**end of header
+
+in the function above the argument @code{run} is used to initiate
+transport service,and defined like this:
+
+@example
+static void run (void *cls, struct
+GNUNET_SERVER_Handle *serv, const struct GNUNET_CONFIGURATION_Handle *cfg) @{
+GNUNET_SERVER_add_handlers (serv, handlers); @}
+@end example
+
+
+Here, @code{GNUNET_SERVER_add_handlers} must be called in the run
+function to add new handlers in the service. The parameter
+@code{handlers} is a list of @code{struct GNUNET_SERVER_MessageHandler}
+to tell the service which function should be called when a particular
+type of message is received, and should be defined in this way:
+
+@example
+static struct GNUNET_SERVER_MessageHandler
+handlers[] = @{ @{&handle_start, NULL, GNUNET_MESSAGE_TYPE_TRANSPORT_START,
+0@}, @{&handle_send, NULL, GNUNET_MESSAGE_TYPE_TRANSPORT_SEND, 0@},
+@{&handle_try_connect, NULL, GNUNET_MESSAGE_TYPE_TRANSPORT_TRY_CONNECT, sizeof
+(struct TryConnectMessage)@}, @{&handle_address_lookup, NULL,
+GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_LOOKUP, 0@}, @{NULL, NULL, 0, 0@} @};
+@end example
+
+
+As shown, the first member of the struct in the first area is a callback
+function, which is called to process the specified message types, given
+as the third member. The second parameter is the closure for the callback
+function, which is set to @code{NULL} in most cases, and the last
+parameter is the expected size of the message of this type, usually we
+set it to 0 to accept variable size, for special cases the exact size of
+the specified message also can be set. In addition, the terminator sign
+depicted as @code{@{NULL, NULL, 0, 0@}} is set in the last aera.
+
+@c ***********************************************************************
+@node Server - Process request message
+@subsubsection Server - Process request message
+@c %**end of header
+
+After the initialization of transport service, the request message would
+be processed. Before handling the main message data, the validity of this
+message should be checked out, e.g., to check whether the size of message
+is correct.
+
+@example
+size = ntohs (message->size); if (size < sizeof (struct
+AddressLookupMessage)) @{ GNUNET_break_op (0); GNUNET_SERVER_receive_done
+(client, GNUNET_SYSERR); return; @}
+@end example
+
+
+Note that, opposite to the construction method of the request message in
+the client, in the server the function @code{nothl} and @code{ntohs}
+should be employed during the extraction of the data from the message, so
+that the data in big endian order can be converted back into little
+endian order. See more in detail please refer to Introduction of
+Big Endian and Little Endian.
+
+Moreover in this example, the name of the transport stored in the message
+is a 0-terminated string, so we should also check whether the name of the
+transport in the received message is 0-terminated:
+
+@example
+nameTransport = (const char *)
+&address[addressLen]; if (nameTransport[size - sizeof (struct
+AddressLookupMessage)
+ - addressLen - 1] != '\0') @{ GNUNET_break_op
+ (0); GNUNET_SERVER_receive_done (client,
+ GNUNET_SYSERR); return; @}
+@end example
+
+Here, @code{GNUNET_SERVER_receive_done} should be called to tell the
+service that the request is done and can receive the next message. The
+argument @code{GNUNET_SYSERR} here indicates that the service didn't
+understand the request message, and the processing of this request would
+be terminated.
+
+In comparison to the aforementioned situation, when the argument is equal
+to @code{GNUNET_OK}, the service would continue to process the requst
+message.
+
+@c ***********************************************************************
+@node Server - Response to client
+@subsubsection Server - Response to client
+@c %**end of header
+
+Once the processing of current request is done, the server should give the
+response to the client. A new @code{struct AddressLookupMessage} would be
+produced by the server in a similar way as the client did and sent to the
+client, but here the type should be
+@code{GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_REPLY} rather than
+@code{GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_LOOKUP} in client.
+@example
+struct
+AddressLookupMessage *msg; size_t len = sizeof (struct AddressLookupMessage) +
+addressLen + strlen (nameTrans) + 1; msg->header->size = htons (len);
+msg->header->type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_REPLY);
+
+// ...
+
+struct GNUNET_SERVER_TransmitContext *tc; tc =
+GNUNET_SERVER_transmit_context_create (client);
+GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0,
+GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_REPLY);
+GNUNET_SERVER_transmit_context_run (tc, rtimeout);
+@end example
+
+
+Note that, there are also a number of other APIs provided to the service
+to send the message.
+
+@c ***********************************************************************
+@node Server - Notification of clients
+@subsubsection Server - Notification of clients
+@c %**end of header
+
+Often a service needs to (repeatedly) transmit notifications to a client
+or a group of clients. In these cases, the client typically has once
+registered for a set of events and then needs to receive a message
+whenever such an event happens (until the client disconnects). The use of
+a notification context can help manage message queues to clients and
+handle disconnects. Notification contexts can be used to send
+individualized messages to a particular client or to broadcast messages
+to a group of clients. An individualized notification might look like
+this:
+
+@example
+ GNUNET_SERVER_notification_context_unicast(nc,
+ client, msg, GNUNET_YES);
+@end example
+
+
+Note that after processing the original registration message for
+notifications, the server code still typically needs to call
+@code{GNUNET_SERVER_receive_done} so that the client can transmit further
+messages to the server.
+
+@c ***********************************************************************
+@node Conversion between Network Byte Order (Big Endian) and Host Byte Order
+@subsubsection Conversion between Network Byte Order (Big Endian) and Host Byte Order
+@c %** subsub? it's a referenced page on the ipc document.
+@c %**end of header
+
+Here we can simply comprehend big endian and little endian as Network Byte
+Order and Host Byte Order respectively. What is the difference between
+both two?
+
+Usually in our host computer we store the data byte as Host Byte Order,
+for example, we store a integer in the RAM which might occupies 4 Byte,
+as Host Byte Order the higher Byte would be stored at the lower address
+of RAM, and the lower Byte would be stored at the higher address of RAM.
+However, contrast to this, Network Byte Order just take the totally
+opposite way to store the data, says, it will store the lower Byte at the
+lower address, and the higher Byte will stay at higher address.
+
+For the current communication of network, we normally exchange the
+information by surveying the data package, every two host wants to
+communicate with each other must send and receive data package through
+network. In order to maintain the identity of data through the
+transmission in the network, the order of the Byte storage must changed
+before sending and after receiving the data.
+
+There ten convenient functions to realize the conversion of Byte Order in
+GNUnet, as following:
+
+@table @asis
+
+@item uint16_t htons(uint16_t hostshort) Convert host byte order to net
+byte order with short int
+@item uint32_t htonl(uint32_t hostlong) Convert host byte
+order to net byte order with long int
+@item uint16_t ntohs(uint16_t netshort)
+Convert net byte order to host byte order with short int
+@item uint32_t
+ntohl(uint32_t netlong) Convert net byte order to host byte order with
+long int
+@item unsigned long long GNUNET_ntohll (unsigned long long netlonglong)
+Convert net byte order to host byte order with long long int
+@item unsigned long long GNUNET_htonll (unsigned long long hostlonglong)
+Convert host byte order to net byte order with long long int
+@item struct GNUNET_TIME_RelativeNBO GNUNET_TIME_relative_hton
+(struct GNUNET_TIME_Relative a) Convert relative time to network byte
+order.
+@item struct GNUNET_TIME_Relative GNUNET_TIME_relative_ntoh
+(struct GNUNET_TIME_RelativeNBO a) Convert relative time from network
+byte order.
+@item struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton
+(struct GNUNET_TIME_Absolute a) Convert relative time to network byte
+order.
+@item struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh
+(struct GNUNET_TIME_AbsoluteNBO a) Convert relative time from network
+byte order.
+@end table
+
+@c ***********************************************************************
+
+@node Cryptography API
+@subsection Cryptography API
+@c %**end of header
+
+The gnunetutil APIs provides the cryptographic primitives used in GNUnet.
+GNUnet uses 2048 bit RSA keys for the session key exchange and for signing
+messages by peers and most other public-key operations. Most researchers
+in cryptography consider 2048 bit RSA keys as secure and practically
+unbreakable for a long time. The API provides functions to create a fresh
+key pair, read a private key from a file (or create a new file if the
+file does not exist), encrypt, decrypt, sign, verify and extraction of
+the public key into a format suitable for network transmission.
+
+For the encryption of files and the actual data exchanged between peers
+GNUnet uses 256-bit AES encryption. Fresh, session keys are negotiated
+for every new connection.@ Again, there is no published technique to
+break this cipher in any realistic amount of time. The API provides
+functions for generation of keys, validation of keys (important for
+checking that decryptions using RSA succeeded), encryption and decryption.
+
+GNUnet uses SHA-512 for computing one-way hash codes. The API provides
+functions to compute a hash over a block in memory or over a file on disk.
+
+The crypto API also provides functions for randomizing a block of memory,
+obtaining a single random number and for generating a permuation of the
+numbers 0 to n-1. Random number generation distinguishes between WEAK and
+STRONG random number quality; WEAK random numbers are pseudo-random
+whereas STRONG random numbers use entropy gathered from the operating
+system.
+
+Finally, the crypto API provides a means to deterministically generate a
+1024-bit RSA key from a hash code. These functions should most likely not
+be used by most applications; most importantly,
+GNUNET_CRYPTO_rsa_key_create_from_hash does not create an RSA-key that
+should be considered secure for traditional applications of RSA.
+
+@c ***********************************************************************
+@node Message Queue API
+@subsection Message Queue API
+@c %**end of header
+
+@strong{ Introduction }@
+Often, applications need to queue messages that
+are to be sent to other GNUnet peers, clients or services. As all of
+GNUnet's message-based communication APIs, by design, do not allow
+messages to be queued, it is common to implement custom message queues
+manually when they are needed. However, writing very similar code in
+multiple places is tedious and leads to code duplication.
+
+MQ (for Message Queue) is an API that provides the functionality to
+implement and use message queues. We intend to eventually replace all of
+the custom message queue implementations in GNUnet with MQ.
+
+@strong{ Basic Concepts }@
+The two most important entities in MQ are queues and envelopes.
+
+Every queue is backed by a specific implementation (e.g. for mesh, stream,
+connection, server client, etc.) that will actually deliver the queued
+messages. For convenience,@ some queues also allow to specify a list of
+message handlers. The message queue will then also wait for incoming
+messages and dispatch them appropriately.
+
+An envelope holds the the memory for a message, as well as metadata
+(Where is the envelope queued? What should happen after it has been
+sent?). Any envelope can only be queued in one message queue.
+
+@strong{ Creating Queues }@
+The following is a list of currently available message queues. Note that
+to avoid layering issues, message queues for higher level APIs are not
+part of @code{libgnunetutil}, but@ the respective API itself provides the
+queue implementation.
+
+@table @asis
+
+@item @code{GNUNET_MQ_queue_for_connection_client}
+Transmits queued messages over a @code{GNUNET_CLIENT_Connection} handle.
+Also supports receiving with message handlers.
+
+@item @code{GNUNET_MQ_queue_for_server_client}
+Transmits queued messages over a @code{GNUNET_SERVER_Client} handle. Does
+not support incoming message handlers.
+
+@item @code{GNUNET_MESH_mq_create} Transmits queued messages over a
+@code{GNUNET_MESH_Tunnel} handle. Does not support incoming message
+handlers.
+
+@item @code{GNUNET_MQ_queue_for_callbacks} This is the most general
+implementation. Instead of delivering and receiving messages with one of
+GNUnet's communication APIs, implementation callbacks are called. Refer to
+"Implementing Queues" for a more detailed explanation.
+@end table
+
+
+@strong{ Allocating Envelopes }@
+A GNUnet message (as defined by the GNUNET_MessageHeader) has three
+parts: The size, the type, and the body.
+
+MQ provides macros to allocate an envelope containing a message
+conveniently, automatically setting the size and type fields of the
+message.
+
+Consider the following simple message, with the body consisting of a
+single number value.
+@c why the empy code function?
+@code{}
+
+@example
+struct NumberMessage @{
+ /** Type: GNUNET_MESSAGE_TYPE_EXAMPLE_1 */
+ struct GNUNET_MessageHeader header; uint32_t number GNUNET_PACKED; @};
+@end example
+
+An envelope containing an instance of the NumberMessage can be
+constructed like this:
+
+@example
+struct GNUNET_MQ_Envelope *ev; struct NumberMessage *msg; ev =
+GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_EXAMPLE_1); msg->number = htonl (42);
+@end example
+
+In the above code, @code{GNUNET_MQ_msg} is a macro. The return value is
+the newly allocated envelope. The first argument must be a pointer to some
+@code{struct} containing a @code{struct GNUNET_MessageHeader header}
+field, while the second argument is the desired message type, in host
+byte order.
+
+The @code{msg} pointer now points to an allocated message, where the
+message type and the message size are already set. The message's size is
+inferred from the type of the @code{msg} pointer: It will be set to
+'sizeof(*msg)', properly converted to network byte order.
+
+If the message body's size is dynamic, the the macro
+@code{GNUNET_MQ_msg_extra} can be used to allocate an envelope whose
+message has additional space allocated after the @code{msg} structure.
+
+If no structure has been defined for the message,
+@code{GNUNET_MQ_msg_header_extra} can be used to allocate additional space
+after the message header. The first argument then must be a pointer to a
+@code{GNUNET_MessageHeader}.
+
+@strong{Envelope Properties}@
+A few functions in MQ allow to set additional properties on envelopes:
+
+@table @asis
+
+@item @code{GNUNET_MQ_notify_sent} Allows to specify a function that will
+be called once the envelope's message@ has been sent irrevocably.
+An envelope can be canceled precisely up to the@ point where the notify
+sent callback has been called.
+
+@item @code{GNUNET_MQ_disable_corking} No corking will be used when
+sending the message. Not every@ queue supports this flag, per default,
+envelopes are sent with corking.@
+
+@end table
+
+
+@strong{Sending Envelopes}@
+Once an envelope has been constructed, it can be queued for sending with
+@code{GNUNET_MQ_send}.
+
+Note that in order to avoid memory leaks, an envelope must either be sent
+(the queue will free it) or destroyed explicitly with
+@code{GNUNET_MQ_discard}.
+
+@strong{Canceling Envelopes}@
+An envelope queued with @code{GNUNET_MQ_send} can be canceled with
+@code{GNUNET_MQ_cancel}. Note that after the notify sent callback has
+been called, canceling a message results in undefined behavior.
+Thus it is unsafe to cancel an envelope that does not have a notify sent
+callback. When canceling an envelope, it is not necessary@ to call
+@code{GNUNET_MQ_discard}, and the envelope can't be sent again.
+
+@strong{ Implementing Queues }@
+@code{TODO}
+
+@c ***********************************************************************
+@node Service API
+@subsection Service API
+@c %**end of header
+
+Most GNUnet code lives in the form of services. Services are processes
+that offer an API for other components of the system to build on. Those
+other components can be command-line tools for users, graphical user
+interfaces or other services. Services provide their API using an IPC
+protocol. For this, each service must listen on either a TCP port or a
+UNIX domain socket; for this, the service implementation uses the server
+API. This use of server is exposed directly to the users of the service
+API. Thus, when using the service API, one is usually also often using
+large parts of the server API. The service API provides various
+convenience functions, such as parsing command-line arguments and the
+configuration file, which are not found in the server API.
+The dual to the service/server API is the client API, which can be used to
+access services.
+
+The most common way to start a service is to use the GNUNET_SERVICE_run
+function from the program's main function. GNUNET_SERVICE_run will then
+parse the command line and configuration files and, based on the options
+found there, start the server. It will then give back control to the main
+program, passing the server and the configuration to the
+GNUNET_SERVICE_Main callback. GNUNET_SERVICE_run will also take care of
+starting the scheduler loop. If this is inappropriate (for example,
+because the scheduler loop is already running), GNUNET_SERVICE_start and
+related functions provide an alternative to GNUNET_SERVICE_run.
+
+When starting a service, the service_name option is used to determine
+which sections in the configuration file should be used to configure the
+service. A typical value here is the name of the src/ sub-directory, for
+example "statistics". The same string would also be given to
+GNUNET_CLIENT_connect to access the service.
+
+Once a service has been initialized, the program should use the
+GNUNET_SERVICE_Main callback to register message handlers using
+GNUNET_SERVER_add_handlers. The service will already have registered a
+handler for the "TEST" message.
+
+The option bitfield (enum GNUNET_SERVICE_Options) determines how a service
+should behave during shutdown. There are three key strategies:
+
+@table @asis
+
+@item instant (GNUNET_SERVICE_OPTION_NONE) Upon receiving the shutdown
+signal from the scheduler, the service immediately terminates the server,
+closing all existing connections with clients.
+@item manual
+(GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN) The service does nothing by itself
+during shutdown. The main program will need to take the appropriate
+action by calling GNUNET_SERVER_destroy or GNUNET_SERVICE_stop (depending
+on how the service was initialized) to terminate the service. This method
+is used by gnunet-service-arm and rather uncommon.
+@item soft
+(GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN) Upon receiving the shutdown signal
+from the scheduler, the service immediately tells the server to stop
+listening for incoming clients. Requests from normal existing clients are
+still processed and the server/service terminates once all normal clients
+have disconnected. Clients that are not expected to ever disconnect (such
+as clients that monitor performance values) can be marked as 'monitor'
+clients using GNUNET_SERVER_client_mark_monitor. Those clients will
+continue to be processed until all 'normal' clients have disconnected.
+Then, the server will terminate, closing the monitor connections.
+This mode is for example used by 'statistics', allowing existing 'normal'
+clients to set (possibly persistent) statistic values before terminating.
+
+@end table
+
+@c ***********************************************************************
+@node Optimizing Memory Consumption of GNUnet's (Multi-) Hash Maps
+@subsection Optimizing Memory Consumption of GNUnet's (Multi-) Hash Maps
+@c %**end of header
+
+A commonly used data structure in GNUnet is a (multi-)hash map. It is most
+often used to map a peer identity to some data structure, but also to map
+arbitrary keys to values (for example to track requests in the distributed
+hash table or in file-sharing). As it is commonly used, the DHT is
+actually sometimes responsible for a large share of GNUnet's overall
+memory consumption (for some processes, 30% is not uncommon). The
+following text documents some API quirks (and their implications for
+applications) that were recently introduced to minimize the footprint of
+the hash map.
+
+
+@c ***********************************************************************
+@menu
+* Analysis::
+* Solution::
+* Migration::
+* Conclusion::
+* Availability::
+@end menu
+
+@node Analysis
+@subsubsection Analysis
+@c %**end of header
+
+The main reason for the "excessive" memory consumption by the hash map is
+that GNUnet uses 512-bit cryptographic hash codes --- and the
+(multi-)hash map also uses the same 512-bit 'struct GNUNET_HashCode'. As
+a result, storing just the keys requires 64 bytes of memory for each key.
+As some applications like to keep a large number of entries in the hash
+map (after all, that's what maps are good for), 64 bytes per hash is
+significant: keeping a pointer to the value and having a linked list for
+collisions consume between 8 and 16 bytes, and 'malloc' may add about the
+same overhead per allocation, putting us in the 16 to 32 byte per entry
+ballpark. Adding a 64-byte key then triples the overall memory
+requirement for the hash map.
+
+To make things "worse", most of the time storing the key in the hash map
+is not required: it is typically already in memory elsewhere! In most
+cases, the values stored in the hash map are some application-specific
+struct that _also_ contains the hash. Here is a simplified example:
+
+@example
+struct MyValue @{
+struct GNUNET_HashCode key; unsigned int my_data; @};
+
+// ...
+val = GNUNET_malloc (sizeof (struct MyValue)); val->key = key; val->my_data =
+42; GNUNET_CONTAINER_multihashmap_put (map, &key, val, ...);
+@end example
+
+This is a common pattern as later the entries might need to be removed,
+and at that time it is convenient to have the key immediately at hand:
+
+@example
+GNUNET_CONTAINER_multihashmap_remove (map, &val->key, val);
+@end example
+
+
+Note that here we end up with two times 64 bytes for the key, plus maybe
+64 bytes total for the rest of the 'struct MyValue' and the map entry in
+the hash map. The resulting redundant storage of the key increases
+overall memory consumption per entry from the "optimal" 128 bytes to 192
+bytes. This is not just an extreme example: overheads in practice are
+actually sometimes close to those highlighted in this example. This is
+especially true for maps with a significant number of entries, as there
+we tend to really try to keep the entries small.
+
+@c ***********************************************************************
+@node Solution
+@subsubsection Solution
+@c %**end of header
+
+The solution that has now been implemented is to @strong{optionally}
+allow the hash map to not make a (deep) copy of the hash but instead have
+a pointer to the hash/key in the entry. This reduces the memory
+consumption for the key from 64 bytes to 4 to 8 bytes. However, it can
+also only work if the key is actually stored in the entry (which is the
+case most of the time) and if the entry does not modify the key (which in
+all of the code I'm aware of has been always the case if there key is
+stored in the entry). Finally, when the client stores an entry in the
+hash map, it @strong{must} provide a pointer to the key within the entry,
+not just a pointer to a transient location of the key. If
+the client code does not meet these requirements, the result is a dangling
+pointer and undefined behavior of the (multi-)hash map API.
+
+@c ***********************************************************************
+@node Migration
+@subsubsection Migration
+@c %**end of header
+
+To use the new feature, first check that the values contain the respective
+key (and never modify it). Then, all calls to
+@code{GNUNET_CONTAINER_multihashmap_put} on the respective map must be
+audited and most likely changed to pass a pointer into the value's struct.
+For the initial example, the new code would look like this:
+
+@example
+struct MyValue @{
+struct GNUNET_HashCode key; unsigned int my_data; @};
+
+// ...
+val = GNUNET_malloc (sizeof (struct MyValue)); val->key = key; val->my_data =
+42; GNUNET_CONTAINER_multihashmap_put (map, &val->key, val, ...);
+@end example
+
+
+Note that @code{&val} was changed to @code{&val->key} in the argument to
+the @code{put} call. This is critical as often @code{key} is on the stack
+or in some other transient data structure and thus having the hash map
+keep a pointer to @code{key} would not work. Only the key inside of
+@code{val} has the same lifetime as the entry in the map (this must of
+course be checked as well). Naturally, @code{val->key} must be
+intiialized before the @code{put} call. Once all @code{put} calls have
+been converted and double-checked, you can change the call to create the
+hash map from
+
+@example
+map =
+GNUNET_CONTAINER_multihashmap_create (SIZE, GNUNET_NO);
+@end example
+
+to
+
+@example
+map = GNUNET_CONTAINER_multihashmap_create (SIZE, GNUNET_YES);
+@end example
+
+If everything was done correctly, you now use about 60 bytes less memory
+per entry in @code{map}. However, if now (or in the future) any call to
+@code{put} does not ensure that the given key is valid until the entry is
+removed from the map, undefined behavior is likely to be observed.
+
+@c ***********************************************************************
+@node Conclusion
+@subsubsection Conclusion
+@c %**end of header
+
+The new optimization can is often applicable and can result in a
+reduction in memory consumption of up to 30% in practice. However, it
+makes the code less robust as additional invariants are imposed on the
+multi hash map client. Thus applications should refrain from enabling the
+new mode unless the resulting performance increase is deemed significant
+enough. In particular, it should generally not be used in new code (wait
+at least until benchmarks exist).
+
+@c ***********************************************************************
+@node Availability
+@subsubsection Availability
+@c %**end of header
+
+The new multi hash map code was committed in SVN 24319 (will be in GNUnet
+0.9.4). Various subsystems (transport, core, dht, file-sharing) were
+previously audited and modified to take advantage of the new capability.
+In particular, memory consumption of the file-sharing service is expected
+to drop by 20-30% due to this change.
+
+@c ***********************************************************************
+@node The CONTAINER_MDLL API
+@subsection The CONTAINER_MDLL API
+@c %**end of header
+
+This text documents the GNUNET_CONTAINER_MDLL API. The
+GNUNET_CONTAINER_MDLL API is similar to the GNUNET_CONTAINER_DLL API in
+that it provides operations for the construction and manipulation of
+doubly-linked lists. The key difference to the (simpler) DLL-API is that
+the MDLL-version allows a single element (instance of a "struct") to be
+in multiple linked lists at the same time.
+
+Like the DLL API, the MDLL API stores (most of) the data structures for
+the doubly-linked list with the respective elements; only the 'head' and
+'tail' pointers are stored "elsewhere" --- and the application needs to
+provide the locations of head and tail to each of the calls in the
+MDLL API. The key difference for the MDLL API is that the "next" and
+"previous" pointers in the struct can no longer be simply called "next"
+and "prev" --- after all, the element may be in multiple doubly-linked
+lists, so we cannot just have one "next" and one "prev" pointer!
+
+The solution is to have multiple fields that must have a name of the
+format "next_XX" and "prev_XX" where "XX" is the name of one of the
+doubly-linked lists. Here is a simple example:
+
+@example
+struct MyMultiListElement @{
+ struct MyMultiListElement *next_ALIST;
+ struct MyMultiListElement *prev_ALIST;
+ struct MyMultiListElement *next_BLIST;
+ struct MyMultiListElement *prev_BLIST;
+ void
+ *data;
+@};
+@end example
+
+
+Note that by convention, we use all-uppercase letters for the list names.
+In addition, the program needs to have a location for the head and tail
+pointers for both lists, for example:
+
+@example
+static struct MyMultiListElement *head_ALIST;
+static struct MyMultiListElement *tail_ALIST;
+static struct MyMultiListElement *head_BLIST;
+static struct MyMultiListElement *tail_BLIST;
+@end example
+
+
+Using the MDLL-macros, we can now insert an element into the ALIST:
+
+@example
+GNUNET_CONTAINER_MDLL_insert (ALIST, head_ALIST, tail_ALIST, element);
+@end example
+
+
+Passing "ALIST" as the first argument to MDLL specifies which of the
+next/prev fields in the 'struct MyMultiListElement' should be used. The
+extra "ALIST" argument and the "_ALIST" in the names of the
+next/prev-members are the only differences between the MDDL and DLL-API.
+Like the DLL-API, the MDLL-API offers functions for inserting (at head,
+at tail, after a given element) and removing elements from the list.
+Iterating over the list should be done by directly accessing the
+"next_XX" and/or "prev_XX" members.
+
+@c ***********************************************************************
+@node The Automatic Restart Manager (ARM)
+@section The Automatic Restart Manager (ARM)
+@c %**end of header
+
+GNUnet's Automated Restart Manager (ARM) is the GNUnet service responsible
+for system initialization and service babysitting. ARM starts and halts
+services, detects configuration changes and restarts services impacted by
+the changes as needed. It's also responsible for restarting services in
+case of crashes and is planned to incorporate automatic debugging for
+diagnosing service crashes providing developers insights about crash
+reasons. The purpose of this document is to give GNUnet developer an idea
+about how ARM works and how to interact with it.
+
+@menu
+* Basic functionality::
+* Key configuration options::
+* Availability2::
+* Reliability::
+@end menu
+
+@c ***********************************************************************
+@node Basic functionality
+@subsection Basic functionality
+@c %**end of header
+
+@itemize @bullet
+@item ARM source code can be found under "src/arm".@ Service processes are
+managed by the functions in "gnunet-service-arm.c" which is controlled
+with "gnunet-arm.c" (main function in that file is ARM's entry point).
+
+@item The functions responsible for communicating with ARM , starting and
+stopping services -including ARM service itself- are provided by the
+ARM API "arm_api.c".@ Function: GNUNET_ARM_connect() returns to the caller
+an ARM handle after setting it to the caller's context (configuration and
+scheduler in use). This handle can be used afterwards by the caller to
+communicate with ARM. Functions GNUNET_ARM_start_service() and
+GNUNET_ARM_stop_service() are used for starting and stopping services
+respectively.
+
+@item A typical example of using these basic ARM services can be found in
+file test_arm_api.c. The test case connects to ARM, starts it, then uses
+it to start a service "resolver", stops the "resolver" then stops "ARM".
+@end itemize
+
+@c ***********************************************************************
+@node Key configuration options
+@subsection Key configuration options
+@c %**end of header
+
+Configurations for ARM and services should be available in a .conf file
+(As an example, see test_arm_api_data.conf). When running ARM, the
+configuration file to use should be passed to the command:@
+@code{@ $ gnunet-arm -s -c configuration_to_use.conf@ }@
+If no configuration is passed, the default configuration file will be used
+(see GNUNET_PREFIX/share/gnunet/defaults.conf which is created from
+contrib/defaults.conf).@ Each of the services is having a section starting
+by the service name between square brackets, for example: "[arm]".
+The following options configure how ARM configures or interacts with the
+various services:
+
+@table @asis
+
+@item PORT Port number on which the service is listening for incoming TCP
+connections. ARM will start the services should it notice a request at
+this port.
+
+@item HOSTNAME Specifies on which host the service is deployed. Note
+that ARM can only start services that are running on the local system
+(but will not check that the hostname matches the local machine name).
+This option is used by the @code{gnunet_client_lib.h} implementation to
+determine which system to connect to. The default is "localhost".
+
+@item BINARY The name of the service binary file.
+
+@item OPTIONS To be passed to the service.
+
+@item PREFIX A command to pre-pend to the actual command, for example,
+running a service with "valgrind" or "gdb"
+
+@item DEBUG Run in debug mode (much verbosity).
+
+@item AUTOSTART ARM will listen to UNIX domain socket and/or TCP port of
+the service and start the service on-demand.
+
+@item FORCESTART ARM will always start this service when the peer
+is started.
+
+@item ACCEPT_FROM IPv4 addresses the service accepts connections from.
+
+@item ACCEPT_FROM6 IPv6 addresses the service accepts connections from.
+
+@end table
+
+
+Options that impact the operation of ARM overall are in the "[arm]"
+section. ARM is a normal service and has (except for AUTOSTART) all of the
+options that other services do. In addition, ARM has the
+following options:
+
+@table @asis
+
+@item GLOBAL_PREFIX Command to be pre-pended to all services that are
+going to run.
+
+@item GLOBAL_POSTFIX Global option that will be supplied to all the
+services that are going to run.
+
+@end table
+
+@c ***********************************************************************
+@node Availability2
+@subsection Availability2
+@c %**end of header
+
+As mentioned before, one of the features provided by ARM is starting
+services on demand. Consider the example of one service "client" that
+wants to connect to another service a "server". The "client" will ask ARM
+to run the "server". ARM starts the "server". The "server" starts
+listening to incoming connections. The "client" will establish a
+connection with the "server". And then, they will start to communicate
+together.@ One problem with that scheme is that it's slow!@
+The "client" service wants to communicate with the "server" service at
+once and is not willing wait for it to be started and listening to
+incoming connections before serving its request.@ One solution for that
+problem will be that ARM starts all services as default services. That
+solution will solve the problem, yet, it's not quite practical, for some
+services that are going to be started can never be used or are going to
+be used after a relatively long time.@
+The approach followed by ARM to solve this problem is as follows:
+
+@itemize @bullet
+
+@item For each service having a PORT field in the configuration file and
+that is not one of the default services ( a service that accepts incoming
+connections from clients), ARM creates listening sockets for all addresses
+associated with that service.
+
+@item The "client" will immediately establish a connection with
+the "server".
+
+@item ARM --- pretending to be the "server" --- will listen on the
+respective port and notice the incoming connection from the "client"
+(but not accept it), instead
+
+@item Once there is an incoming connection, ARM will start the "server",
+passing on the listen sockets (now, the service is started and can do its
+work).
+
+@item Other client services now can directly connect directly to the
+"server".
+
+@end itemize
+
+@c ***********************************************************************
+@node Reliability
+@subsection Reliability
+
+One of the features provided by ARM, is the automatic restart of crashed
+services.@ ARM needs to know which of the running services died. Function
+"gnunet-service-arm.c/maint_child_death()" is responsible for that. The
+function is scheduled to run upon receiving a SIGCHLD signal. The
+function, then, iterates ARM's list of services running and monitors
+which service has died (crashed). For all crashing services, ARM restarts
+them.@
+Now, considering the case of a service having a serious problem causing it
+to crash each time it's started by ARM. If ARM keeps blindly restarting
+such a service, we are going to have the pattern:
+start-crash-restart-crash-restart-crash and so forth!! Which is of course
+not practical.@
+For that reason, ARM schedules the service to be restarted after waiting
+for some delay that grows exponentially with each crash/restart of that
+service.@ To clarify the idea, considering the following example:
+
+@itemize @bullet
+
+@item Service S crashed.
+
+@item ARM receives the SIGCHLD and inspects its list of services to find
+the dead one(s).
+
+@item ARM finds S dead and schedules it for restarting after "backoff"
+time which is initially set to 1ms. ARM will double the backoff time
+correspondent to S (now backoff(S) = 2ms)
+
+@item Because there is a severe problem with S, it crashed again.
+
+@item Again ARM receives the SIGCHLD and detects that it's S again that's
+crashed. ARM schedules it for restarting but after its new backoff time
+(which became 2ms), and doubles its backoff time (now backoff(S) = 4).
+
+@item and so on, until backoff(S) reaches a certain threshold
+(EXPONENTIAL_BACKOFF_THRESHOLD is set to half an hour), after reaching it,
+backoff(S) will remain half an hour, hence ARM won't be busy for a lot of
+time trying to restart a problematic service.
+@end itemize
+
+@c ***********************************************************************
+@node GNUnet's TRANSPORT Subsystem
+@section GNUnet's TRANSPORT Subsystem
+@c %**end of header
+
+This chapter documents how the GNUnet transport subsystem works. The
+GNUnet transport subsystem consists of three main components: the
+transport API (the interface used by the rest of the system to access the
+transport service), the transport service itself (most of the interesting
+functions, such as choosing transports, happens here) and the transport
+plugins. A transport plugin is a concrete implementation for how two
+GNUnet peers communicate; many plugins exist, for example for
+communication via TCP, UDP, HTTP, HTTPS and others. Finally, the
+transport subsystem uses supporting code, especially the NAT/UPnP
+library to help with tasks such as NAT traversal.
+
+Key tasks of the transport service include:
+
+@itemize @bullet
+
+@item Create our HELLO message, notify clients and neighbours if our HELLO
+changes (using NAT library as necessary)
+
+@item Validate HELLOs from other peers (send PING), allow other peers to
+validate our HELLO's addresses (send PONG)
+
+@item Upon request, establish connections to other peers (using address
+selection from ATS subsystem) and maintain them (again using PINGs and
+PONGs) as long as desired
+
+@item Accept incoming connections, give ATS service the opportunity to
+switch communication channels
+
+@item Notify clients about peers that have connected to us or that have
+been disconnected from us
+
+@item If a (stateful) connection goes down unexpectedly (without explicit
+DISCONNECT), quickly attempt to recover (without notifying clients) but do
+notify clients quickly if reconnecting fails
+
+@item Send (payload) messages arriving from clients to other peers via
+transport plugins and receive messages from other peers, forwarding
+those to clients
+
+@item Enforce inbound traffic limits (using flow-control if it is
+applicable); outbound traffic limits are enforced by CORE, not by us (!)
+
+@item Enforce restrictions on P2P connection as specified by the blacklist
+configuration and blacklisting clients
+@end itemize
+
+
+Note that the term "clients" in the list above really refers to the
+GNUnet-CORE service, as CORE is typically the only client of the
+transport service.
+
+@menu
+* Address validation protocol::
+@end menu
+
+@node Address validation protocol
+@subsection Address validation protocol
+@c %**end of header
+
+This section documents how the GNUnet transport service validates
+connections with other peers. It is a high-level description of the
+protocol necessary to understand the details of the implementation. It
+should be noted that when we talk about PING and PONG messages in this
+section, we refer to transport-level PING and PONG messages, which are
+different from core-level PING and PONG messages (both in implementation
+and function).
+
+The goal of transport-level address validation is to minimize the chances
+of a successful man-in-the-middle attack against GNUnet peers on the
+transport level. Such an attack would not allow the adversary to decrypt
+the P2P transmissions, but a successful attacker could at least measure
+traffic volumes and latencies (raising the adversaries capablities by
+those of a global passive adversary in the worst case). The scenarios we
+are concerned about is an attacker, Mallory, giving a HELLO to Alice that
+claims to be for Bob, but contains Mallory's IP address instead of Bobs
+(for some transport). Mallory would then forward the traffic to Bob (by
+initiating a connection to Bob and claiming to be Alice). As a further
+complication, the scheme has to work even if say Alice is behind a NAT
+without traversal support and hence has no address of her own (and thus
+Alice must always initiate the connection to Bob).
+
+An additional constraint is that HELLO messages do not contain a
+cryptographic signature since other peers must be able to edit
+(i.e. remove) addresses from the HELLO at any time (this was not true in
+GNUnet 0.8.x). A basic @strong{assumption} is that each peer knows the
+set of possible network addresses that it @strong{might} be reachable
+under (so for example, the external IP address of the NAT plus the LAN
+address(es) with the respective ports).
+
+The solution is the following. If Alice wants to validate that a given
+address for Bob is valid (i.e. is actually established @strong{directly}
+with the intended target), it sends a PING message over that connection
+to Bob. Note that in this case, Alice initiated the connection so only
+she knows which address was used for sure (Alice maybe behind NAT, so
+whatever address Bob sees may not be an address Alice knows she has). Bob
+checks that the address given in the PING is actually one of his addresses
+(does not belong to Mallory), and if it is, sends back a PONG (with a
+signature that says that Bob owns/uses the address from the PING). Alice
+checks the signature and is happy if it is valid and the address in the
+PONG is the address she used. This is similar to the 0.8.x protocol where
+the HELLO contained a signature from Bob for each address used by Bob.
+Here, the purpose code for the signature is
+@code{GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_OWN}. After this, Alice will
+remember Bob's address and consider the address valid for a while (12h in
+the current implementation). Note that after this exchange, Alice only
+considers Bob's address to be valid, the connection itself is not
+considered 'established'. In particular, Alice may have many addresses
+for Bob that she considers valid.
+
+The PONG message is protected with a nonce/challenge against replay
+attacks and uses an expiration time for the signature (but those are
+almost implementation details).
+
+@node NAT library
+@section NAT library
+@c %**end of header
+
+The goal of the GNUnet NAT library is to provide a general-purpose API for
+NAT traversal @strong{without} third-party support. So protocols that
+involve contacting a third peer to help establish a connection between
+two peers are outside of the scope of this API. That does not mean that
+GNUnet doesn't support involving a third peer (we can do this with the
+distance-vector transport or using application-level protocols), it just
+means that the NAT API is not concerned with this possibility. The API is
+written so that it will work for IPv6-NAT in the future as well as
+current IPv4-NAT. Furthermore, the NAT API is always used, even for peers
+that are not behind NAT --- in that case, the mapping provided is simply
+the identity.
+
+NAT traversal is initiated by calling @code{GNUNET_NAT_register}. Given a
+set of addresses that the peer has locally bound to (TCP or UDP), the NAT
+library will return (via callback) a (possibly longer) list of addresses
+the peer @strong{might} be reachable under. Internally, depending on the
+configuration, the NAT library will try to punch a hole (using UPnP) or
+just "know" that the NAT was manually punched and generate the respective
+external IP address (the one that should be globally visible) based on
+the given information.
+
+The NAT library also supports ICMP-based NAT traversal. Here, the other
+peer can request connection-reversal by this peer (in this special case,
+the peer is even allowed to configure a port number of zero). If the NAT
+library detects a connection-reversal request, it returns the respective
+target address to the client as well. It should be noted that
+connection-reversal is currently only intended for TCP, so other plugins
+@strong{must} pass @code{NULL} for the reversal callback. Naturally, the
+NAT library also supports requesting connection reversal from a remote
+peer (@code{GNUNET_NAT_run_client}).
+
+Once initialized, the NAT handle can be used to test if a given address is
+possibly a valid address for this peer (@code{GNUNET_NAT_test_address}).
+This is used for validating our addresses when generating PONGs.
+
+Finally, the NAT library contains an API to test if our NAT configuration
+is correct. Using @code{GNUNET_NAT_test_start} @strong{before} binding to
+the respective port, the NAT library can be used to test if the
+configuration works. The test function act as a local client, initialize
+the NAT traversal and then contact a @code{gnunet-nat-server} (running by
+default on @code{gnunet.org}) and ask for a connection to be established.
+This way, it is easy to test if the current NAT configuration is valid.
+
+@node Distance-Vector plugin
+@section Distance-Vector plugin
+@c %**end of header
+
+The Distance Vector (DV) transport is a transport mechanism that allows
+peers to act as relays for each other, thereby connecting peers that would
+otherwise be unable to connect. This gives a larger connection set to
+applications that may work better with more peers to choose from (for
+example, File Sharing and/or DHT).
+
+The Distance Vector transport essentially has two functions. The first is
+"gossiping" connection information about more distant peers to directly
+connected peers. The second is taking messages intended for non-directly
+connected peers and encapsulating them in a DV wrapper that contains the
+required information for routing the message through forwarding peers. Via
+gossiping, optimal routes through the known DV neighborhood are discovered
+and utilized and the message encapsulation provides some benefits in
+addition to simply getting the message from the correct source to the
+proper destination.
+
+The gossiping function of DV provides an up to date routing table of
+peers that are available up to some number of hops. We call this a
+fisheye view of the network (like a fish, nearby objects are known while
+more distant ones unknown). Gossip messages are sent only to directly
+connected peers, but they are sent about other knowns peers within the
+"fisheye distance". Whenever two peers connect, they immediately gossip
+to each other about their appropriate other neighbors. They also gossip
+about the newly connected peer to previously
+connected neighbors. In order to keep the routing tables up to date,
+disconnect notifications are propogated as gossip as well (because
+disconnects may not be sent/received, timeouts are also used remove
+stagnant routing table entries).
+
+Routing of messages via DV is straightforward. When the DV transport is
+notified of a message destined for a non-direct neighbor, the appropriate
+forwarding peer is selected, and the base message is encapsulated in a DV
+message which contains information about the initial peer and the intended
+recipient. At each forwarding hop, the initial peer is validated (the
+forwarding peer ensures that it has the initial peer in its neighborhood,
+otherwise the message is dropped). Next the base message is
+re-encapsulated in a new DV message for the next hop in the forwarding
+chain (or delivered to the current peer, if it has arrived at the
+destination).
+
+Assume a three peer network with peers Alice, Bob and Carol. Assume that
+Alice <-> Bob and Bob <-> Carol are direct (e.g. over TCP or UDP
+transports) connections, but that Alice cannot directly connect to Carol.
+This may be the case due to NAT or firewall restrictions, or perhaps
+based on one of the peers respective configurations. If the Distance
+Vector transport is enabled on all three peers, it will automatically
+discover (from the gossip protocol) that Alice and Carol can connect via
+Bob and provide a "virtual" Alice <-> Carol connection. Routing between
+Alice and Carol happens as follows; Alice creates a message destined for
+Carol and notifies the DV transport about it. The DV transport at Alice
+looks up Carol in the routing table and finds that the message must be
+sent through Bob for Carol. The message is encapsulated setting Alice as
+the initiator and Carol as the destination and sent to Bob. Bob receives
+the messages, verifies both Alice and Carol are known to Bob, and re-wraps
+the message in a new DV message for Carol. The DV transport at Carol
+receives this message, unwraps the original message, and delivers it to
+Carol as though it came directly from Alice.
+
+@node SMTP plugin
+@section SMTP plugin
+@c %**end of header
+
+This section describes the new SMTP transport plugin for GNUnet as it
+exists in the 0.7.x and 0.8.x branch. SMTP support is currently not
+available in GNUnet 0.9.x. This page also describes the transport layer
+abstraction (as it existed in 0.7.x and 0.8.x) in more detail and gives
+some benchmarking results. The performance results presented are quite
+old and maybe outdated at this point.
+
+@itemize @bullet
+@item Why use SMTP for a peer-to-peer transport?
+@item SMTPHow does it work?
+@item How do I configure my peer?
+@item How do I test if it works?
+@item How fast is it?
+@item Is there any additional documentation?
+@end itemize
+
+
+@menu
+* Why use SMTP for a peer-to-peer transport?::
+* How does it work?::
+* How do I configure my peer?::
+* How do I test if it works?::
+* How fast is it?::
+@end menu
+
+@node Why use SMTP for a peer-to-peer transport?
+@subsection Why use SMTP for a peer-to-peer transport?
+@c %**end of header
+
+There are many reasons why one would not want to use SMTP:
+
+@itemize @bullet
+@item SMTP is using more bandwidth than TCP, UDP or HTTP
+@item SMTP has a much higher latency.
+@item SMTP requires significantly more computation (encoding and decoding
+time) for the peers.
+@item SMTP is significantly more complicated to configure.
+@item SMTP may be abused by tricking GNUnet into sending mail to@
+non-participating third parties.
+@end itemize
+
+So why would anybody want to use SMTP?
+@itemize @bullet
+@item SMTP can be used to contact peers behind NAT boxes (in virtual
+private networks).
+@item SMTP can be used to circumvent policies that limit or prohibit
+peer-to-peer traffic by masking as "legitimate" traffic.
+@item SMTP uses E-mail addresses which are independent of a specific IP,
+which can be useful to address peers that use dynamic IP addresses.
+@item SMTP can be used to initiate a connection (e.g. initial address
+exchange) and peers can then negotiate the use of a more efficient
+protocol (e.g. TCP) for the actual communication.
+@end itemize
+
+In summary, SMTP can for example be used to send a message to a peer
+behind a NAT box that has a dynamic IP to tell the peer to establish a
+TCP connection to a peer outside of the private network. Even an
+extraordinary overhead for this first message would be irrelevant in this
+type of situation.
+
+@node How does it work?
+@subsection How does it work?
+@c %**end of header
+
+When a GNUnet peer needs to send a message to another GNUnet peer that has
+advertised (only) an SMTP transport address, GNUnet base64-encodes the
+message and sends it in an E-mail to the advertised address. The
+advertisement contains a filter which is placed in the E-mail header,
+such that the receiving host can filter the tagged E-mails and forward it
+to the GNUnet peer process. The filter can be specified individually by
+each peer and be changed over time. This makes it impossible to censor
+GNUnet E-mail messages by searching for a generic filter.
+
+@node How do I configure my peer?
+@subsection How do I configure my peer?
+@c %**end of header
+
+First, you need to configure @code{procmail} to filter your inbound E-mail
+for GNUnet traffic. The GNUnet messages must be delivered into a pipe, for
+example @code{/tmp/gnunet.smtp}. You also need to define a filter that is
+used by @command{procmail} to detect GNUnet messages. You are free to
+choose whichever filter you like, but you should make sure that it does
+not occur in your other E-mail. In our example, we will use
+@code{X-mailer: GNUnet}. The @code{~/.procmailrc} configuration file then
+looks like this:
+
+@example
+:0:
+* ^X-mailer: GNUnet
+/tmp/gnunet.smtp
+# where do you want your other e-mail delivered to (default: /var/spool/mail/)
+:0: /var/spool/mail/
+@end example
+
+After adding this file, first make sure that your regular E-mail still
+works (e.g. by sending an E-mail to yourself). Then edit the GNUnet
+configuration. In the section @code{SMTP} you need to specify your E-mail
+address under @code{EMAIL}, your mail server (for outgoing mail) under
+@code{SERVER}, the filter (X-mailer: GNUnet in the example) under
+@code{FILTER} and the name of the pipe under @code{PIPE}.@ The completed
+section could then look like this:
+
+@example
+EMAIL = me@@mail.gnu.org MTU = 65000 SERVER = mail.gnu.org:25 FILTER =
+"X-mailer: GNUnet" PIPE = /tmp/gnunet.smtp
+@end example
+
+Finally, you need to add @code{smtp} to the list of @code{TRANSPORTS} in
+the @code{GNUNETD} section. GNUnet peers will use the E-mail address that
+you specified to contact your peer until the advertisement times out.
+Thus, if you are not sure if everything works properly or if you are not
+planning to be online for a long time, you may want to configure this
+timeout to be short, e.g. just one hour. For this, set
+@code{HELLOEXPIRES} to @code{1} in the @code{GNUNETD} section.
+
+This should be it, but you may probably want to test it first.
+
+@node How do I test if it works?
+@subsection How do I test if it works?
+@c %**end of header
+
+Any transport can be subjected to some rudimentary tests using the
+@code{gnunet-transport-check} tool. The tool sends a message to the local
+node via the transport and checks that a valid message is received. While
+this test does not involve other peers and can not check if firewalls or
+other network obstacles prohibit proper operation, this is a great
+testcase for the SMTP transport since it tests pretty much nearly all of
+the functionality.
+
+@code{gnunet-transport-check} should only be used without running
+@code{gnunetd} at the same time. By default, @code{gnunet-transport-check}
+tests all transports that are specified in the configuration file. But
+you can specifically test SMTP by giving the option
+@code{--transport=smtp}.
+
+Note that this test always checks if a transport can receive and send.
+While you can configure most transports to only receive or only send
+messages, this test will only work if you have configured the transport
+to send and receive messages.
+
+@node How fast is it?
+@subsection How fast is it?
+@c %**end of header
+
+We have measured the performance of the UDP, TCP and SMTP transport layer
+directly and when used from an application using the GNUnet core.
+Measureing just the transport layer gives the better view of the actual
+overhead of the protocol, whereas evaluating the transport from the
+application puts the overhead into perspective from a practical point of
+view.
+
+The loopback measurements of the SMTP transport were performed on three
+different machines spanning a range of modern SMTP configurations. We
+used a PIII-800 running RedHat 7.3 with the Purdue Computer Science
+configuration which includes filters for spam. We also used a Xenon 2 GHZ
+with a vanilla RedHat 8.0 sendmail configuration. Furthermore, we used
+qmail on a PIII-1000 running Sorcerer GNU Linux (SGL). The numbers for
+UDP and TCP are provided using the SGL configuration. The qmail benchmark
+uses qmail's internal filtering whereas the sendmail benchmarks relies on
+procmail to filter and deliver the mail. We used the transport layer to
+send a message of b bytes (excluding transport protocol headers) directly
+to the local machine. This way, network latency and packet loss on the
+wire have no impact on the timings. n messages were sent sequentially over
+the transport layer, sending message i+1 after the i-th message was
+received. All messages were sent over the same connection and the time to
+establish the connection was not taken into account since this overhead is
+miniscule in practice --- as long as a connection is used for a
+significant number of messages.
+
+@multitable @columnfractions .20 .15 .15 .15 .15 .15
+@headitem Transport @tab UDP @tab TCP @tab SMTP (Purdue sendmail) @tab SMTP (RH 8.0) @tab SMTP (SGL qmail)
+@item 11 bytes @tab 31 ms @tab 55 ms @tab 781 s @tab 77 s @tab 24 s
+@item 407 bytes @tab 37 ms @tab 62 ms @tab 789 s @tab 78 s @tab 25 s
+@item 1,221 bytes @tab 46 ms @tab 73 ms @tab 804 s @tab 78 s @tab 25 s
+@end multitable
+
+The benchmarks show that UDP and TCP are, as expected, both significantly
+faster compared with any of the SMTP services. Among the SMTP
+implementations, there can be significant differences depending on the
+SMTP configuration. Filtering with an external tool like procmail that
+needs to re-parse its configuration for each mail can be very expensive.
+Applying spam filters can also significantly impact the performance of
+the underlying SMTP implementation. The microbenchmark shows that SMTP
+can be a viable solution for initiating peer-to-peer sessions: a couple of
+seconds to connect to a peer are probably not even going to be noticed by
+users. The next benchmark measures the possible throughput for a
+transport. Throughput can be measured by sending multiple messages in
+parallel and measuring packet loss. Note that not only UDP but also the
+TCP transport can actually loose messages since the TCP implementation
+drops messages if the @code{write} to the socket would block. While the
+SMTP protocol never drops messages itself, it is often so
+slow that only a fraction of the messages can be sent and received in the
+given time-bounds. For this benchmark we report the message loss after
+allowing t time for sending m messages. If messages were not sent (or
+received) after an overall timeout of t, they were considered lost. The
+benchmark was performed using two Xeon 2 GHZ machines running RedHat 8.0
+with sendmail. The machines were connected with a direct 100 MBit ethernet
+connection.@ Figures udp1200, tcp1200 and smtp-MTUs show that the
+throughput for messages of size 1,200 octects is 2,343 kbps, 3,310 kbps
+and 6 kbps for UDP, TCP and SMTP respectively. The high per-message
+overhead of SMTP can be improved by increasing the MTU, for example, an
+MTU of 12,000 octets improves the throughput to 13 kbps as figure
+smtp-MTUs shows. Our research paper) has some more details on the
+benchmarking results.
+
+@node Bluetooth plugin
+@section Bluetooth plugin
+@c %**end of header
+
+This page describes the new Bluetooth transport plugin for GNUnet. The
+plugin is still in the testing stage so don't expect it to work
+perfectly. If you have any questions or problems just post them here or
+ask on the IRC channel.
+
+@itemize @bullet
+@item What do I need to use the Bluetooth plugin transport?
+@item BluetoothHow does it work?
+@item What possible errors should I be aware of?
+@item How do I configure my peer?
+@item How can I test it?
+@end itemize
+
+
+
+@menu
+* What do I need to use the Bluetooth plugin transport?::
+* How does it work2?::
+* What possible errors should I be aware of?::
+* How do I configure my peer2?::
+* How can I test it?::
+* The implementation of the Bluetooth transport plugin::
+@end menu
+
+@node What do I need to use the Bluetooth plugin transport?
+@subsection What do I need to use the Bluetooth plugin transport?
+@c %**end of header
+
+If you are a Linux user and you want to use the Bluetooth transport plugin
+you should install the BlueZ development libraries (if they aren't already
+installed). For instructions about how to install the libraries you should
+check out the BlueZ site
+(@uref{http://www.bluez.org/, http://www.bluez.org}). If you don't know if
+you have the necesarry libraries, don't worry, just run the GNUnet
+configure script and you will be able to see a notification at the end
+which will warn you if you don't have the necessary libraries.
+
+If you are a Windows user you should have installed the
+@emph{MinGW}/@emph{MSys2} with the latest updates (especially the
+@emph{ws2bth} header). If this is your first build of GNUnet on Windows
+you should check out the SBuild repository. It will semi-automatically
+assembles a @emph{MinGW}/@emph{MSys2} installation with a lot of extra
+packages which are needed for the GNUnet build. So this will ease your
+work!@ Finally you just have to be sure that you have the correct drivers
+for your Bluetooth device installed and that your device is on and in a
+discoverable mode. The Windows Bluetooth Stack supports only the RFCOMM
+protocol so we cannot turn on your device programatically!
+
+@c FIXME: Change to unique title
+@node How does it work2?
+@subsection How does it work2?
+@c %**end of header
+
+The Bluetooth transport plugin uses virtually the same code as the WLAN
+plugin and only the helper binary is different. The helper takes a single
+argument, which represents the interface name and is specified in the
+configuration file. Here are the basic steps that are followed by the
+helper binary used on Linux:
+
+@itemize @bullet
+@item it verifies if the name corresponds to a Bluetooth interface name
+@item it verifies if the iterface is up (if it is not, it tries to bring
+it up)
+@item it tries to enable the page and inquiry scan in order to make the
+device discoverable and to accept incoming connection requests
+@emph{The above operations require root access so you should start the
+transport plugin with root privileges.}
+@item it finds an available port number and registers a SDP service which
+will be used to find out on which port number is the server listening on
+and switch the socket in listening mode
+@item it sends a HELLO message with its address
+@item finally it forwards traffic from the reading sockets to the STDOUT
+and from the STDIN to the writing socket
+@end itemize
+
+Once in a while the device will make an inquiry scan to discover the
+nearby devices and it will send them randomly HELLO messages for peer
+discovery.
+
+@node What possible errors should I be aware of?
+@subsection What possible errors should I be aware of?
+@c %**end of header
+
+@emph{This section is dedicated for Linux users}
+
+Well there are many ways in which things could go wrong but I will try to
+present some tools that you could use to debug and some scenarios.
+
+@itemize @bullet
+
+@item @code{bluetoothd -n -d} : use this command to enable logging in the
+foreground and to print the logging messages
+
+@item @code{hciconfig}: can be used to configure the Bluetooth devices.
+If you run it without any arguments it will print information about the
+state of the interfaces. So if you receive an error that the device
+couldn't be brought up you should try to bring it manually and to see if
+it works (use @code{hciconfig -a hciX up}). If you can't and the
+Bluetooth address has the form 00:00:00:00:00:00 it means that there is
+something wrong with the D-Bus daemon or with the Bluetooth daemon. Use
+@code{bluetoothd} tool to see the logs
+
+@item @code{sdptool} can be used to control and interogate SDP servers.
+If you encounter problems regarding the SDP server (like the SDP server is
+down) you should check out if the D-Bus daemon is running correctly and to
+see if the Bluetooth daemon started correctly(use @code{bluetoothd} tool).
+Also, sometimes the SDP service could work but somehow the device couldn't
+register his service. Use @code{sdptool browse [dev-address]} to see if
+the service is registered. There should be a service with the name of the
+interface and GNUnet as provider.
+
+@item @code{hcitool} : another useful tool which can be used to configure
+the device and to send some particular commands to it.
+
+@item @code{hcidump} : could be used for low level debugging
+@end itemize
+
+@c FIXME: A more unique name
+@node How do I configure my peer2?
+@subsection How do I configure my peer2?
+@c %**end of header
+
+On Linux, you just have to be sure that the interface name corresponds to
+the one that you want to use. Use the @code{hciconfig} tool to check that.
+By default it is set to hci0 but you can change it.
+
+A basic configuration looks like this:
+
+@example
+[transport-bluetooth]
+# Name of the interface (typically hciX)
+INTERFACE = hci0
+# Real hardware, no testing
+TESTMODE = 0 TESTING_IGNORE_KEYS = ACCEPT_FROM;
+@end example
+
+In order to use the Bluetooth transport plugin when the transport service
+is started, you must add the plugin name to the default transport service
+plugins list. For example:
+
+@example
+[transport] ... PLUGINS = dns bluetooth ...
+@end example
+
+If you want to use only the Bluetooth plugin set
+@emph{PLUGINS = bluetooth}
+
+On Windows, you cannot specify which device to use. The only thing that
+you should do is to add @emph{bluetooth} on the plugins list of the
+transport service.
+
+@node How can I test it?
+@subsection How can I test it?
+@c %**end of header
+
+If you have two Bluetooth devices on the same machine which use Linux you
+must:
+
+@itemize @bullet
+
+@item create two different file configuration (one which will use the
+first interface (@emph{hci0}) and the other which will use the second
+interface (@emph{hci1})). Let's name them @emph{peer1.conf} and
+@emph{peer2.conf}.
+
+@item run @emph{gnunet-peerinfo -c peerX.conf -s} in order to generate the
+peers private keys. The @strong{X} must be replace with 1 or 2.
+
+@item run @emph{gnunet-arm -c peerX.conf -s -i=transport} in order to
+start the transport service. (Make sure that you have "bluetooth" on the
+transport plugins list if the Bluetooth transport service doesn't start.)
+
+@item run @emph{gnunet-peerinfo -c peer1.conf -s} to get the first peer's
+ID. If you already know your peer ID (you saved it from the first
+command), this can be skipped.
+
+@item run @emph{gnunet-transport -c peer2.conf -p=PEER1_ID -s} to start
+sending data for benchmarking to the other peer.
+
+@end itemize
+
+
+This scenario will try to connect the second peer to the first one and
+then start sending data for benchmarking.
+
+On Windows you cannot test the plugin functionality using two Bluetooth
+devices from the same machine because after you install the drivers there
+will occur some conflicts between the Bluetooth stacks. (At least that is
+what happend on my machine : I wasn't able to use the Bluesoleil stack and
+the WINDCOMM one in the same time).
+
+If you have two different machines and your configuration files are good
+you can use the same scenario presented on the begining of this section.
+
+Another way to test the plugin functionality is to create your own
+application which will use the GNUnet framework with the Bluetooth
+transport service.
+
+@node The implementation of the Bluetooth transport plugin
+@subsection The implementation of the Bluetooth transport plugin
+@c %**end of header
+
+This page describes the implementation of the Bluetooth transport plugin.
+
+First I want to remind you that the Bluetooth transport plugin uses
+virtually the same code as the WLAN plugin and only the helper binary is
+different. Also the scope of the helper binary from the Bluetooth
+transport plugin is the same as the one used for the wlan transport
+plugin: it acceses the interface and then it forwards traffic in both
+directions between the Bluetooth interface and stdin/stdout of the
+process involved.
+
+The Bluetooth plugin transport could be used both on Linux and Windows
+platforms.
+
+@itemize @bullet
+@item Linux functionality
+@item Windows functionality
+@item Pending Features
+@end itemize
+
+
+
+@menu
+* Linux functionality::
+* THE INITIALIZATION::
+* THE LOOP::
+* Details about the broadcast implementation::
+* Windows functionality::
+* Pending features::
+@end menu
+
+@node Linux functionality
+@subsubsection Linux functionality
+@c %**end of header
+
+In order to implement the plugin functionality on Linux I used the BlueZ
+stack. For the communication with the other devices I used the RFCOMM
+protocol. Also I used the HCI protocol to gain some control over the
+device. The helper binary takes a single argument (the name of the
+Bluetooth interface) and is separated in two stages:
+
+@c %** 'THE INITIALIZATION' should be in bigger letters or stand out, not
+@c %** starting a new section?
+@node THE INITIALIZATION
+@subsubsection THE INITIALIZATION
+
+@itemize @bullet
+@item first, it checks if we have root privilegies
+(@emph{Remember that we need to have root privilegies in order to be able
+to bring the interface up if it is down or to change its state.}).
+
+@item second, it verifies if the interface with the given name exists.
+
+@strong{If the interface with that name exists and it is a Bluetooth
+interface:}
+
+@item it creates a RFCOMM socket which will be used for listening and call
+the @emph{open_device} method
+
+On the @emph{open_device} method:
+@itemize @bullet
+@item creates a HCI socket used to send control events to the the device
+@item searches for the device ID using the interface name
+@item saves the device MAC address
+@item checks if the interface is down and tries to bring it UP
+@item checks if the interface is in discoverable mode and tries to make it
+discoverable
+@item closes the HCI socket and binds the RFCOMM one
+@item switches the RFCOMM socket in listening mode
+@item registers the SDP service (the service will be used by the other
+devices to get the port on which this device is listening on)
+@end itemize
+
+@item drops the root privilegies
+
+@strong{If the interface is not a Bluetooth interface the helper exits
+with a suitable error}
+@end itemize
+
+@c %** Same as for @node entry above
+@node THE LOOP
+@subsubsection THE LOOP
+
+The helper binary uses a list where it saves all the connected neighbour
+devices (@emph{neighbours.devices}) and two buffers (@emph{write_pout} and
+@emph{write_std}). The first message which is send is a control message
+with the device's MAC address in order to announce the peer presence to
+the neighbours. Here are a short description of what happens in the main
+loop:
+
+@itemize @bullet
+@item Every time when it receives something from the STDIN it processes
+the data and saves the message in the first buffer (@emph{write_pout}).
+When it has something in the buffer, it gets the destination address from
+the buffer, searches the destination address in the list (if there is no
+connection with that device, it creates a new one and saves it to the
+list) and sends the message.
+@item Every time when it receives something on the listening socket it
+accepts the connection and saves the socket on a list with the reading
+sockets. @item Every time when it receives something from a reading
+socket it parses the message, verifies the CRC and saves it in the
+@emph{write_std} buffer in order to be sent later to the STDOUT.
+@end itemize
+
+So in the main loop we use the select function to wait until one of the
+file descriptor saved in one of the two file descriptors sets used is
+ready to use. The first set (@emph{rfds}) represents the reading set and
+it could contain the list with the reading sockets, the STDIN file
+descriptor or the listening socket. The second set (@emph{wfds}) is the
+writing set and it could contain the sending socket or the STDOUT file
+descriptor. After the select function returns, we check which file
+descriptor is ready to use and we do what is supposed to do on that kind
+of event. @emph{For example:} if it is the listening socket then we
+accept a new connection and save the socket in the reading list; if it is
+the STDOUT file descriptor, then we write to STDOUT the message from the
+@emph{write_std} buffer.
+
+To find out on which port a device is listening on we connect to the local
+SDP server and searche the registered service for that device.
+
+@emph{You should be aware of the fact that if the device fails to connect
+to another one when trying to send a message it will attempt one more
+time. If it fails again, then it skips the message.}
+@emph{Also you should know that the transport Bluetooth plugin has
+support for @strong{broadcast messages}.}
+
+@node Details about the broadcast implementation
+@subsubsection Details about the broadcast implementation
+@c %**end of header
+
+First I want to point out that the broadcast functionality for the CONTROL
+messages is not implemented in a conventional way. Since the inquiry scan
+time is too big and it will take some time to send a message to all the
+discoverable devices I decided to tackle the problem in a different way.
+Here is how I did it:
+
+@itemize @bullet
+@item If it is the first time when I have to broadcast a message I make an
+inquiry scan and save all the devices' addresses to a vector.
+@item After the inquiry scan ends I take the first address from the list
+and I try to connect to it. If it fails, I try to connect to the next one.
+If it succeeds, I save the socket to a list and send the message to the
+device.
+@item When I have to broadcast another message, first I search on the list
+for a new device which I'm not connected to. If there is no new device on
+the list I go to the beginning of the list and send the message to the
+old devices. After 5 cycles I make a new inquiry scan to check out if
+there are new discoverable devices and save them to the list. If there
+are no new discoverable devices I reset the cycling counter and go again
+through the old list and send messages to the devices saved in it.
+@end itemize
+
+@strong{Therefore}:
+
+@itemize @bullet
+@item every time when I have a broadcast message I look up on the list
+for a new device and send the message to it
+@item if I reached the end of the list for 5 times and I'm connected to
+all the devices from the list I make a new inquiry scan.
+@emph{The number of the list's cycles after an inquiry scan could be
+increased by redefining the MAX_LOOPS variable}
+@item when there are no new devices I send messages to the old ones.
+@end itemize
+
+Doing so, the broadcast control messages will reach the devices but with
+delay.
+
+@emph{NOTICE:} When I have to send a message to a certain device first I
+check on the broadcast list to see if we are connected to that device. If
+not we try to connect to it and in case of success we save the address and
+the socket on the list. If we are already connected to that device we
+simply use the socket.
+
+@node Windows functionality
+@subsubsection Windows functionality
+@c %**end of header
+
+For Windows I decided to use the Microsoft Bluetooth stack which has the
+advantage of coming standard from Windows XP SP2. The main disadvantage is
+that it only supports the RFCOMM protocol so we will not be able to have
+a low level control over the Bluetooth device. Therefore it is the user
+responsability to check if the device is up and in the discoverable mode.
+Also there are no tools which could be used for debugging in order to read
+the data coming from and going to a Bluetooth device, which obviously
+hindered my work. Another thing that slowed down the implementation of the
+plugin (besides that I wasn't too accomodated with the win32 API) was that
+there were some bugs on MinGW regarding the Bluetooth. Now they are solved
+but you should keep in mind that you should have the latest updates
+(especially the @emph{ws2bth} header).
+
+Besides the fact that it uses the Windows Sockets, the Windows
+implemenation follows the same principles as the Linux one:
+
+@itemize @bullet
+@item It has a initalization part where it initializes the
+Windows Sockets, creates a RFCOMM socket which will be binded and switched
+to the listening mode and registers a SDP service. In the Microsoft
+Bluetooth API there are two ways to work with the SDP:
+@itemize @bullet
+@item an easy way which works with very simple service records
+@item a hard way which is useful when you need to update or to delete the
+record
+@end itemize
+@end itemize
+
+Since I only needed the SDP service to find out on which port the device
+is listening on and that did not change, I decided to use the easy way.
+In order to register the service I used the @emph{WSASetService} function
+and I generated the @emph{Universally Unique Identifier} with the
+@emph{guidgen.exe} Windows's tool.
+
+In the loop section the only difference from the Linux implementation is
+that I used the GNUNET_NETWORK library for functions like @emph{accept},
+@emph{bind}, @emph{connect} or @emph{select}. I decided to use the
+GNUNET_NETWORK library because I also needed to interact with the STDIN
+and STDOUT handles and on Windows the select function is only defined for
+sockets, and it will not work for arbitrary file handles.
+
+Another difference between Linux and Windows implementation is that in
+Linux, the Bluetooth address is represented in 48 bits while in Windows is
+represented in 64 bits. Therefore I had to do some changes on
+@emph{plugin_transport_wlan} header.
+
+Also, currently on Windows the Bluetooth plugin doesn't have support for
+broadcast messages. When it receives a broadcast message it will skip it.
+
+@node Pending features
+@subsubsection Pending features
+@c %**end of header
+
+@itemize @bullet
+@item Implement the broadcast functionality on Windows @emph{(currently
+working on)}
+@item Implement a testcase for the helper :@ @emph{The testcase
+consists of a program which emaluates the plugin and uses the helper. It
+will simulate connections, disconnections and data transfers.}
+@end itemize
+
+If you have a new idea about a feature of the plugin or suggestions about
+how I could improve the implementation you are welcome to comment or to
+contact me.
+
+@node WLAN plugin
+@section WLAN plugin
+@c %**end of header
+
+This section documents how the wlan transport plugin works. Parts which
+are not implemented yet or could be better implemented are described at
+the end.
+
+@cindex ats subsystem
+@node The ATS Subsystem
+@section The ATS Subsystem
+@c %**end of header
+
+ATS stands for "automatic transport selection", and the function of ATS in
+GNUnet is to decide on which address (and thus transport plugin) should
+be used for two peers to communicate, and what bandwidth limits should be
+imposed on such an individual connection. To help ATS make an informed
+decision, higher-level services inform the ATS service about their
+requirements and the quality of the service rendered. The ATS service
+also interacts with the transport service to be appraised of working
+addresses and to communicate its resource allocation decisions. Finally,
+the ATS service's operation can be observed using a monitoring API.
+
+The main logic of the ATS service only collects the available addresses,
+their performance characteristics and the applications requirements, but
+does not make the actual allocation decision. This last critical step is
+left to an ATS plugin, as we have implemented (currently three) different
+allocation strategies which differ significantly in their performance and
+maturity, and it is still unclear if any particular plugin is generally
+superior.
+
+@cindex core subsystem
+@cindex CORE subsystem
+@node GNUnet's CORE Subsystem
+@section GNUnet's CORE Subsystem
+@c %**end of header
+
+The CORE subsystem in GNUnet is responsible for securing link-layer
+communications between nodes in the GNUnet overlay network. CORE builds
+on the TRANSPORT subsystem which provides for the actual, insecure,
+unreliable link-layer communication (for example, via UDP or WLAN), and
+then adds fundamental security to the connections:
+
+@itemize @bullet
+@item confidentiality with so-called perfect forward secrecy; we use
+ECDHE@footnote{@uref{http://en.wikipedia.org/wiki/Elliptic_curve_
+Diffie%E2%80%93Hellman, Elliptic-curve Diffie---Hellman}}
+powered by Curve25519
+@footnote{@uref{http://cr.yp.to/ecdh.html, Curve25519}} for the key
+exchange and then use symmetric encryption, encrypting with both AES-256
+@footnote{@uref{http://en.wikipedia.org/wiki/Rijndael, AES-256}} and
+Twofish @footnote{@uref{http://en.wikipedia.org/wiki/Twofish, Twofish}}
+@item @uref{http://en.wikipedia.org/wiki/Authentication, authentication}
+is achieved by signing the ephemeral keys using Ed25519
+@footnote{@uref{http://ed25519.cr.yp.to/, Ed25519}}, a deterministic
+variant of ECDSA
+@footnote{@uref{http://en.wikipedia.org/wiki/ECDSA, ECDSA}}
+@item integrity protection (using SHA-512
+@footnote{@uref{http://en.wikipedia.org/wiki/SHA-2, SHA-512}} to do
+encrypt-then-MAC
+@footnote{@uref{http://en.wikipedia.org/wiki/Authenticated_encryption,
+encrypt-then-MAC}})
+@item Replay
+@footnote{@uref{http://en.wikipedia.org/wiki/Replay_attack, replay}}
+protection (using nonces, timestamps, challenge-response,
+message counters and ephemeral keys)
+@item liveness (keep-alive messages, timeout)
+@end itemize
+
+@menu
+* Limitations::
+* When is a peer "connected"?::
+* libgnunetcore::
+* The CORE Client-Service Protocol::
+* The CORE Peer-to-Peer Protocol::
+@end menu
+
+@cindex core subsystem limitations
+@node Limitations
+@subsection Limitations
+@c %**end of header
+
+CORE does not perform
+@uref{http://en.wikipedia.org/wiki/Routing, routing}; using CORE it is
+only possible to communicate with peers that happen to already be
+"directly" connected with each other. CORE also does not have an
+API to allow applications to establish such "direct" connections --- for
+this, applications can ask TRANSPORT, but TRANSPORT might not be able to
+establish a "direct" connection. The TOPOLOGY subsystem is responsible for
+trying to keep a few "direct" connections open at all times. Applications
+that need to talk to particular peers should use the CADET subsystem, as
+it can establish arbitrary "indirect" connections.
+
+Because CORE does not perform routing, CORE must only be used directly by
+applications that either perform their own routing logic (such as
+anonymous file-sharing) or that do not require routing, for example
+because they are based on flooding the network. CORE communication is
+unreliable and delivery is possibly out-of-order. Applications that
+require reliable communication should use the CADET service. Each
+application can only queue one message per target peer with the CORE
+service at any time; messages cannot be larger than approximately
+63 kilobytes. If messages are small, CORE may group multiple messages
+(possibly from different applications) prior to encryption. If permitted
+by the application (using the @uref{http://baus.net/on-tcp_cork/, cork}
+option), CORE may delay transmissions to facilitate grouping of multiple
+small messages. If cork is not enabled, CORE will transmit the message as
+soon as TRANSPORT allows it (TRANSPORT is responsible for limiting
+bandwidth and congestion control). CORE does not allow flow control;
+applications are expected to process messages at line-speed. If flow
+control is needed, applications should use the CADET service.
+
+@cindex when is a peer connected
+@node When is a peer "connected"?
+@subsection When is a peer "connected"?
+@c %**end of header
+
+In addition to the security features mentioned above, CORE also provides
+one additional key feature to applications using it, and that is a
+limited form of protocol-compatibility checking. CORE distinguishes
+between TRANSPORT-level connections (which enable communication with other
+peers) and application-level connections. Applications using the CORE API
+will (typically) learn about application-level connections from CORE, and
+not about TRANSPORT-level connections. When a typical application uses
+CORE, it will specify a set of message types
+(from @code{gnunet_protocols.h}) that it understands. CORE will then
+notify the application about connections it has with other peers if and
+only if those applications registered an intersecting set of message
+types with their CORE service. Thus, it is quite possible that CORE only
+exposes a subset of the established direct connections to a particular
+application --- and different applications running above CORE might see
+different sets of connections at the same time.
+
+A special case are applications that do not register a handler for any
+message type.
+CORE assumes that these applications merely want to monitor connections
+(or "all" messages via other callbacks) and will notify those applications
+about all connections. This is used, for example, by the
+@code{gnunet-core} command-line tool to display the active connections.
+Note that it is also possible that the TRANSPORT service has more active
+connections than the CORE service, as the CORE service first has to
+perform a key exchange with connecting peers before exchanging information
+about supported message types and notifying applications about the new
+connection.
+
+@cindex libgnunetcore
+@node libgnunetcore
+@subsection libgnunetcore
+@c %**end of header
+
+The CORE API (defined in @file{gnunet_core_service.h}) is the basic
+messaging API used by P2P applications built using GNUnet. It provides
+applications the ability to send and receive encrypted messages to the
+peer's "directly" connected neighbours.
+
+As CORE connections are generally "direct" connections,@ applications must
+not assume that they can connect to arbitrary peers this way, as "direct"
+connections may not always be possible. Applications using CORE are
+notified about which peers are connected. Creating new "direct"
+connections must be done using the TRANSPORT API.
+
+The CORE API provides unreliable, out-of-order delivery. While the
+implementation tries to ensure timely, in-order delivery, both message
+losses and reordering are not detected and must be tolerated by the
+application. Most important, the core will NOT perform retransmission if
+messages could not be delivered.
+
+Note that CORE allows applications to queue one message per connected
+peer. The rate at which each connection operates is influenced by the
+preferences expressed by local application as well as restrictions
+imposed by the other peer. Local applications can express their
+preferences for particular connections using the "performance" API of the
+ATS service.
+
+Applications that require more sophisticated transmission capabilities
+such as TCP-like behavior, or if you intend to send messages to arbitrary
+remote peers, should use the CADET API.
+
+The typical use of the CORE API is to connect to the CORE service using
+@code{GNUNET_CORE_connect}, process events from the CORE service (such as
+peers connecting, peers disconnecting and incoming messages) and send
+messages to connected peers using
+@code{GNUNET_CORE_notify_transmit_ready}. Note that applications must
+cancel pending transmission requests if they receive a disconnect event
+for a peer that had a transmission pending; furthermore, queueing more
+than one transmission request per peer per application using the
+service is not permitted.
+
+The CORE API also allows applications to monitor all communications of the
+peer prior to encryption (for outgoing messages) or after decryption (for
+incoming messages). This can be useful for debugging, diagnostics or to
+establish the presence of cover traffic (for anonymity). As monitoring
+applications are often not interested in the payload, the monitoring
+callbacks can be configured to only provide the message headers (including
+the message type and size) instead of copying the full data stream to the
+monitoring client.
+
+The init callback of the @code{GNUNET_CORE_connect} function is called
+with the hash of the public key of the peer. This public key is used to
+identify the peer globally in the GNUnet network. Applications are
+encouraged to check that the provided hash matches the hash that they are
+using (as theoretically the application may be using a different
+configuration file with a different private key, which would result in
+hard to find bugs).
+
+As with most service APIs, the CORE API isolates applications from crashes
+of the CORE service. If the CORE service crashes, the application will see
+disconnect events for all existing connections. Once the connections are
+re-established, the applications will be receive matching connect events.
+
+@cindex core clinet-service protocol
+@node The CORE Client-Service Protocol
+@subsection The CORE Client-Service Protocol
+@c %**end of header
+
+This section describes the protocol between an application using the CORE
+service (the client) and the CORE service process itself.
+
+
+@menu
+* Setup2::
+* Notifications::
+* Sending::
+@end menu
+
+@node Setup2
+@subsubsection Setup2
+@c %**end of header
+
+When a client connects to the CORE service, it first sends a
+@code{InitMessage} which specifies options for the connection and a set of
+message type values which are supported by the application. The options
+bitmask specifies which events the client would like to be notified about.
+The options include:
+
+@table @asis
+@item GNUNET_CORE_OPTION_NOTHING No notifications
+@item GNUNET_CORE_OPTION_STATUS_CHANGE Peers connecting and disconnecting
+@item GNUNET_CORE_OPTION_FULL_INBOUND All inbound messages (after
+decryption) with full payload
+@item GNUNET_CORE_OPTION_HDR_INBOUND Just the @code{MessageHeader}
+of all inbound messages
+@item GNUNET_CORE_OPTION_FULL_OUTBOUND All outbound
+messages (prior to encryption) with full payload
+@item GNUNET_CORE_OPTION_HDR_OUTBOUND Just the @code{MessageHeader} of all
+outbound messages
+@end table
+
+Typical applications will only monitor for connection status changes.
+
+The CORE service responds to the @code{InitMessage} with an
+@code{InitReplyMessage} which contains the peer's identity. Afterwards,
+both CORE and the client can send messages.
+
+@node Notifications
+@subsubsection Notifications
+@c %**end of header
+
+The CORE will send @code{ConnectNotifyMessage}s and
+@code{DisconnectNotifyMessage}s whenever peers connect or disconnect from
+the CORE (assuming their type maps overlap with the message types
+registered by the client). When the CORE receives a message that matches
+the set of message types specified during the @code{InitMessage} (or if
+monitoring is enabled in for inbound messages in the options), it sends a
+@code{NotifyTrafficMessage} with the peer identity of the sender and the
+decrypted payload. The same message format (except with
+@code{GNUNET_MESSAGE_TYPE_CORE_NOTIFY_OUTBOUND} for the message type) is
+used to notify clients monitoring outbound messages; here, the peer
+identity given is that of the receiver.
+
+@node Sending
+@subsubsection Sending
+@c %**end of header
+
+When a client wants to transmit a message, it first requests a
+transmission slot by sending a @code{SendMessageRequest} which specifies
+the priority, deadline and size of the message. Note that these values
+may be ignored by CORE. When CORE is ready for the message, it answers
+with a @code{SendMessageReady} response. The client can then transmit the
+payload with a @code{SendMessage} message. Note that the actual message
+size in the @code{SendMessage} is allowed to be smaller than the size in
+the original request. A client may at any time send a fresh
+@code{SendMessageRequest}, which then superceeds the previous
+@code{SendMessageRequest}, which is then no longer valid. The client can
+tell which @code{SendMessageRequest} the CORE service's
+@code{SendMessageReady} message is for as all of these messages contain a
+"unique" request ID (based on a counter incremented by the client
+for each request).
+
+@node The CORE Peer-to-Peer Protocol
+@subsection The CORE Peer-to-Peer Protocol
+@c %**end of header
+
+
+@menu
+* Creating the EphemeralKeyMessage::
+* Establishing a connection::
+* Encryption and Decryption::
+* Type maps::
+@end menu
+
+@cindex EphemeralKeyMessage creation
+@node Creating the EphemeralKeyMessage
+@subsubsection Creating the EphemeralKeyMessage
+@c %**end of header
+
+When the CORE service starts, each peer creates a fresh ephemeral (ECC)
+public-private key pair and signs the corresponding
+@code{EphemeralKeyMessage} with its long-term key (which we usually call
+the peer's identity; the hash of the public long term key is what results
+in a @code{struct GNUNET_PeerIdentity} in all GNUnet APIs. The ephemeral
+key is ONLY used for an ECDHE@footnote{@uref{http://en.wikipedia.org/wiki/
+Elliptic_curve_Diffie%E2%80%93Hellman, Elliptic-curve Diffie---Hellman}}
+exchange by the CORE service to establish symmetric session keys. A peer
+will use the same @code{EphemeralKeyMessage} for all peers for
+@code{REKEY_FREQUENCY}, which is usually 12 hours. After that time, it
+will create a fresh ephemeral key (forgetting the old one) and broadcast
+the new @code{EphemeralKeyMessage} to all connected peers, resulting in
+fresh symmetric session keys. Note that peers independently decide on
+when to discard ephemeral keys; it is not a protocol violation to discard
+keys more often. Ephemeral keys are also never stored to disk; restarting
+a peer will thus always create a fresh ephemeral key. The use of ephemeral
+keys is what provides @uref{http://en.wikipedia.org/wiki/Forward_secrecy,
+forward secrecy}.
+
+Just before transmission, the @code{EphemeralKeyMessage} is patched to
+reflect the current sender_status, which specifies the current state of
+the connection from the point of view of the sender. The possible values
+are:
+
+@itemize @bullet
+@item @code{KX_STATE_DOWN} Initial value, never used on the network
+@item @code{KX_STATE_KEY_SENT} We sent our ephemeral key, do not know the
+key of the other peer
+@item @code{KX_STATE_KEY_RECEIVED} This peer has received a valid
+ephemeral key of the other peer, but we are waiting for the other peer to
+confirm it's authenticity (ability to decode) via challenge-response.
+@item @code{KX_STATE_UP} The connection is fully up from the point of
+view of the sender (now performing keep-alives)
+@item @code{KX_STATE_REKEY_SENT} The sender has initiated a rekeying
+operation; the other peer has so far failed to confirm a working
+connection using the new ephemeral key
+@end itemize
+
+@node Establishing a connection
+@subsubsection Establishing a connection
+@c %**end of header
+
+Peers begin their interaction by sending a @code{EphemeralKeyMessage} to
+the other peer once the TRANSPORT service notifies the CORE service about
+the connection.
+A peer receiving an @code{EphemeralKeyMessage} with a status
+indicating that the sender does not have the receiver's ephemeral key, the
+receiver's @code{EphemeralKeyMessage} is sent in response.
+Additionally, if the receiver has not yet confirmed the authenticity of
+the sender, it also sends an (encrypted)@code{PingMessage} with a
+challenge (and the identity of the target) to the other peer. Peers
+receiving a @code{PingMessage} respond with an (encrypted)
+@code{PongMessage} which includes the challenge. Peers receiving a
+@code{PongMessage} check the challenge, and if it matches set the
+connection to @code{KX_STATE_UP}.
+
+@node Encryption and Decryption
+@subsubsection Encryption and Decryption
+@c %**end of header
+
+All functions related to the key exchange and encryption/decryption of
+messages can be found in @file{gnunet-service-core_kx.c} (except for the
+cryptographic primitives, which are in @file{util/crypto*.c}).
+Given the key material from ECDHE, a Key derivation function
+@footnote{@uref{https://en.wikipedia.org/wiki/Key_derivation_function, Key
+derivation function}} is used to derive two pairs of encryption and
+decryption keys for AES-256 and TwoFish, as well as initialization vectors
+and authentication keys (for HMAC@footnote{@uref{https://en.wikipedia.org/
+wiki/HMAC, HMAC}}). The HMAC is computed over the encrypted payload.
+Encrypted messages include an iv_seed and the HMAC in the header.
+
+Each encrypted message in the CORE service includes a sequence number and
+a timestamp in the encrypted payload. The CORE service remembers the
+largest observed sequence number and a bit-mask which represents which of
+the previous 32 sequence numbers were already used.
+Messages with sequence numbers lower than the largest observed sequence
+number minus 32 are discarded. Messages with a timestamp that is less
+than @code{REKEY_TOLERANCE} off (5 minutes) are also discarded. This of
+course means that system clocks need to be reasonably synchronized for
+peers to be able to communicate. Additionally, as the ephemeral key
+changes every 12 hours, a peer would not even be able to decrypt messages
+older than 12 hours.
+
+@node Type maps
+@subsubsection Type maps
+@c %**end of header
+
+Once an encrypted connection has been established, peers begin to exchange
+type maps. Type maps are used to allow the CORE service to determine which
+(encrypted) connections should be shown to which applications. A type map
+is an array of 65536 bits representing the different types of messages
+understood by applications using the CORE service. Each CORE service
+maintains this map, simply by setting the respective bit for each message
+type supported by any of the applications using the CORE service. Note
+that bits for message types embedded in higher-level protocols (such as
+MESH) will not be included in these type maps.
+
+Typically, the type map of a peer will be sparse. Thus, the CORE service
+attempts to compress its type map using @code{gzip}-style compression
+("deflate") prior to transmission. However, if the compression fails to
+compact the map, the map may also be transmitted without compression
+(resulting in @code{GNUNET_MESSAGE_TYPE_CORE_COMPRESSED_TYPE_MAP} or
+@code{GNUNET_MESSAGE_TYPE_CORE_BINARY_TYPE_MAP} messages respectively).
+Upon receiving a type map, the respective CORE service notifies
+applications about the connection to the other peer if they support any
+message type indicated in the type map (or no message type at all).
+If the CORE service experience a connect or disconnect event from an
+application, it updates its type map (setting or unsetting the respective
+bits) and notifies its neighbours about the change.
+The CORE services of the neighbours then in turn generate connect and
+disconnect events for the peer that sent the type map for their respective
+applications. As CORE messages may be lost, the CORE service confirms
+receiving a type map by sending back a
+@code{GNUNET_MESSAGE_TYPE_CORE_CONFIRM_TYPE_MAP}. If such a confirmation
+(with the correct hash of the type map) is not received, the sender will
+retransmit the type map (with exponential back-off).
+
+@cindex cadet subsystem
+@cindex CADET
+@node GNUnet's CADET subsystem
+@section GNUnet's CADET subsystem
+
+The CADET subsystem in GNUnet is responsible for secure end-to-end
+communications between nodes in the GNUnet overlay network. CADET builds
+on the CORE subsystem which provides for the link-layer communication and
+then adds routing, forwarding and additional security to the connections.
+CADET offers the same cryptographic services as CORE, but on an
+end-to-end level. This is done so peers retransmitting traffic on behalf
+of other peers cannot access the payload data.
+
+@itemize @bullet
+@item CADET provides confidentiality with so-called perfect forward
+secrecy; we use ECDHE powered by Curve25519 for the key exchange and then
+use symmetric encryption, encrypting with both AES-256 and Twofish
+@item authentication is achieved by signing the ephemeral keys using
+Ed25519, a deterministic variant of ECDSA
+@item integrity protection (using SHA-512 to do encrypt-then-MAC, although
+only 256 bits are sent to reduce overhead)
+@item replay protection (using nonces, timestamps, challenge-response,
+message counters and ephemeral keys)
+@item liveness (keep-alive messages, timeout)
+@end itemize
+
+Additional to the CORE-like security benefits, CADET offers other
+properties that make it a more universal service than CORE.
+
+@itemize @bullet
+@item CADET can establish channels to arbitrary peers in GNUnet. If a
+peer is not immediately reachable, CADET will find a path through the
+network and ask other peers to retransmit the traffic on its behalf.
+@item CADET offers (optional) reliability mechanisms. In a reliable
+channel traffic is guaranteed to arrive complete, unchanged and in-order.
+@item CADET takes care of flow and congestion control mechanisms, not
+allowing the sender to send more traffic than the receiver or the network
+are able to process.
+@end itemize
+
+@menu
+* libgnunetcadet::
+@end menu
+
+@cindex libgnunetcadet
+@node libgnunetcadet
+@subsection libgnunetcadet
+
+
+The CADET API (defined in @file{gnunet_cadet_service.h}) is the
+messaging API used by P2P applications built using GNUnet.
+It provides applications the ability to send and receive encrypted
+messages to any peer participating in GNUnet.
+The API is heavily base on the CORE API.
+
+CADET delivers messages to other peers in "channels".
+A channel is a permanent connection defined by a destination peer
+(identified by its public key) and a port number.
+Internally, CADET tunnels all channels towards a destiantion peer
+using one session key and relays the data on multiple "connections",
+independent from the channels.
+
+Each channel has optional paramenters, the most important being the
+reliability flag.
+Should a message get lost on TRANSPORT/CORE level, if a channel is
+created with as reliable, CADET will retransmit the lost message and
+deliver it in order to the destination application.
+
+To communicate with other peers using CADET, it is necessary to first
+connect to the service using @code{GNUNET_CADET_connect}.
+This function takes several parameters in form of callbacks, to allow the
+client to react to various events, like incoming channels or channels that
+terminate, as well as specify a list of ports the client wishes to listen
+to (at the moment it is not possible to start listening on further ports
+once connected, but nothing prevents a client to connect several times to
+CADET, even do one connection per listening port).
+The function returns a handle which has to be used for any further
+interaction with the service.
+
+To connect to a remote peer a client has to call the
+@code{GNUNET_CADET_channel_create} function. The most important parameters
+given are the remote peer's identity (it public key) and a port, which
+specifies which application on the remote peer to connect to, similar to
+TCP/UDP ports. CADET will then find the peer in the GNUnet network and
+establish the proper low-level connections and do the necessary key
+exchanges to assure and authenticated, secure and verified communication.
+Similar to @code{GNUNET_CADET_connect},@code{GNUNET_CADET_create_channel}
+returns a handle to interact with the created channel.
+
+For every message the client wants to send to the remote application,
+@code{GNUNET_CADET_notify_transmit_ready} must be called, indicating the
+channel on which the message should be sent and the size of the message
+(but not the message itself!). Once CADET is ready to send the message,
+the provided callback will fire, and the message contents are provided to
+this callback.
+
+Please note the CADET does not provide an explicit notification of when a
+channel is connected. In loosely connected networks, like big wireless
+mesh networks, this can take several seconds, even minutes in the worst
+case. To be alerted when a channel is online, a client can call
+@code{GNUNET_CADET_notify_transmit_ready} immediately after
+@code{GNUNET_CADET_create_channel}. When the callback is activated, it
+means that the channel is online. The callback can give 0 bytes to CADET
+if no message is to be sent, this is ok.
+
+If a transmission was requested but before the callback fires it is no
+longer needed, it can be cancelled with
+@code{GNUNET_CADET_notify_transmit_ready_cancel}, which uses the handle
+given back by @code{GNUNET_CADET_notify_transmit_ready}.
+As in the case of CORE, only one message can be requested at a time: a
+client must not call @code{GNUNET_CADET_notify_transmit_ready} again until
+the callback is called or the request is cancelled.
+
+When a channel is no longer needed, a client can call
+@code{GNUNET_CADET_channel_destroy} to get rid of it.
+Note that CADET will try to transmit all pending traffic before notifying
+the remote peer of the destruction of the channel, including
+retransmitting lost messages if the channel was reliable.
+
+Incoming channels, channels being closed by the remote peer, and traffic
+on any incoming or outgoing channels are given to the client when CADET
+executes the callbacks given to it at the time of
+@code{GNUNET_CADET_connect}.
+
+Finally, when an application no longer wants to use CADET, it should call
+@code{GNUNET_CADET_disconnect}, but first all channels and pending
+transmissions must be closed (otherwise CADET will complain).
+
+@cindex nse subsystem
+@cindex NSE
+@node GNUnet's NSE subsystem
+@section GNUnet's NSE subsystem
+
+
+NSE stands for @dfn{Network Size Estimation}. The NSE subsystem provides
+other subsystems and users with a rough estimate of the number of peers
+currently participating in the GNUnet overlay.
+The computed value is not a precise number as producing a precise number
+in a decentralized, efficient and secure way is impossible.
+While NSE's estimate is inherently imprecise, NSE also gives the expected
+range. For a peer that has been running in a stable network for a
+while, the real network size will typically (99.7% of the time) be in the
+range of [2/3 estimate, 3/2 estimate]. We will now give an overview of the
+algorithm used to calculate the estimate;
+all of the details can be found in this technical report.
+
+@c FIXME: link to the report.
+
+@menu
+* Motivation::
+* Principle::
+* libgnunetnse::
+* The NSE Client-Service Protocol::
+* The NSE Peer-to-Peer Protocol::
+@end menu
+
+@node Motivation
+@subsection Motivation
+
+
+Some subsytems, like DHT, need to know the size of the GNUnet network to
+optimize some parameters of their own protocol. The decentralized nature
+of GNUnet makes efficient and securely counting the exact number of peers
+infeasable. Although there are several decentralized algorithms to count
+the number of peers in a system, so far there is none to do so securely.
+Other protocols may allow any malicious peer to manipulate the final
+result or to take advantage of the system to perform
+@dfn{Denial of Service} (DoS) attacks against the network.
+GNUnet's NSE protocol avoids these drawbacks.
+
+
+
+@menu
+* Security::
+@end menu
+
+@cindex NSE security
+@cindex nse security
+@node Security
+@subsubsection Security
+
+
+The NSE subsystem is designed to be resilient against these attacks.
+It uses @uref{http://en.wikipedia.org/wiki/Proof-of-work_system, proofs
+of work} to prevent one peer from impersonating a large number of
+participants, which would otherwise allow an adversary to artifically
+inflate the estimate.
+The DoS protection comes from the time-based nature of the protocol:
+the estimates are calculated periodically and out-of-time traffic is
+either ignored or stored for later retransmission by benign peers.
+In particular, peers cannot trigger global network communication at will.
+
+@cindex NSE principle
+@cindex nse principle
+@node Principle
+@subsection Principle
+
+
+The algorithm calculates the estimate by finding the globally closest
+peer ID to a random, time-based value.
+
+The idea is that the closer the ID is to the random value, the more
+"densely packed" the ID space is, and therefore, more peers are in the
+network.
+
+
+
+@menu
+* Example::
+* Algorithm::
+* Target value::
+* Timing::
+* Controlled Flooding::
+* Calculating the estimate::
+@end menu
+
+@node Example
+@subsubsection Example
+
+
+Suppose all peers have IDs between 0 and 100 (our ID space), and the
+random value is 42.
+If the closest peer has the ID 70 we can imagine that the average
+"distance" between peers is around 30 and therefore the are around 3
+peers in the whole ID space. On the other hand, if the closest peer has
+the ID 44, we can imagine that the space is rather packed with peers,
+maybe as much as 50 of them.
+Naturally, we could have been rather unlucky, and there is only one peer
+and happens to have the ID 44. Thus, the current estimate is calculated
+as the average over multiple rounds, and not just a single sample.
+
+@node Algorithm
+@subsubsection Algorithm
+
+
+Given that example, one can imagine that the job of the subsystem is to
+efficiently communicate the ID of the closest peer to the target value
+to all the other peers, who will calculate the estimate from it.
+
+@node Target value
+@subsubsection Target value
+
+@c %**end of header
+
+The target value itself is generated by hashing the current time, rounded
+down to an agreed value. If the rounding amount is 1h (default) and the
+time is 12:34:56, the time to hash would be 12:00:00. The process is
+repeated each rouning amount (in this example would be every hour).
+Every repetition is called a round.
+
+@node Timing
+@subsubsection Timing
+@c %**end of header
+
+The NSE subsystem has some timing control to avoid everybody broadcasting
+its ID all at one. Once each peer has the target random value, it
+compares its own ID to the target and calculates the hypothetical size of
+the network if that peer were to be the closest.
+Then it compares the hypothetical size with the estimate from the previous
+rounds. For each value there is an assiciated point in the period,
+let's call it "broadcast time". If its own hypothetical estimate
+is the same as the previous global estimate, its "broadcast time" will be
+in the middle of the round. If its bigger it will be earlier and if its
+smaller (the most likely case) it will be later. This ensures that the
+peers closests to the target value start broadcasting their ID the first.
+
+@node Controlled Flooding
+@subsubsection Controlled Flooding
+
+@c %**end of header
+
+When a peer receives a value, first it verifies that it is closer than the
+closest value it had so far, otherwise it answers the incoming message
+with a message containing the better value. Then it checks a proof of
+work that must be included in the incoming message, to ensure that the
+other peer's ID is not made up (otherwise a malicious peer could claim to
+have an ID of exactly the target value every round). Once validated, it
+compares the brodcast time of the received value with the current time
+and if it's not too early, sends the received value to its neighbors.
+Otherwise it stores the value until the correct broadcast time comes.
+This prevents unnecessary traffic of sub-optimal values, since a better
+value can come before the broadcast time, rendering the previous one
+obsolete and saving the traffic that would have been used to broadcast it
+to the neighbors.
+
+@node Calculating the estimate
+@subsubsection Calculating the estimate
+
+@c %**end of header
+
+Once the closest ID has been spread across the network each peer gets the
+exact distance betweed this ID and the target value of the round and
+calculates the estimate with a mathematical formula described in the tech
+report. The estimate generated with this method for a single round is not
+very precise. Remember the case of the example, where the only peer is the
+ID 44 and we happen to generate the target value 42, thinking there are
+50 peers in the network. Therefore, the NSE subsystem remembers the last
+64 estimates and calculates an average over them, giving a result of which
+usually has one bit of uncertainty (the real size could be half of the
+estimate or twice as much). Note that the actual network size is
+calculated in powers of two of the raw input, thus one bit of uncertainty
+means a factor of two in the size estimate.
+
+@cindex libgnunetnse
+@node libgnunetnse
+@subsection libgnunetnse
+
+@c %**end of header
+
+The NSE subsystem has the simplest API of all services, with only two
+calls: @code{GNUNET_NSE_connect} and @code{GNUNET_NSE_disconnect}.
+
+The connect call gets a callback function as a parameter and this function
+is called each time the network agrees on an estimate. This usually is
+once per round, with some exceptions: if the closest peer has a late
+local clock and starts spreading his ID after everyone else agreed on a
+value, the callback might be activated twice in a round, the second value
+being always bigger than the first. The default round time is set to
+1 hour.
+
+The disconnect call disconnects from the NSE subsystem and the callback
+is no longer called with new estimates.
+
+
+
+@menu
+* Results::
+* Examples2::
+@end menu
+
+@node Results
+@subsubsection Results
+
+@c %**end of header
+
+The callback provides two values: the average and the
+@uref{http://en.wikipedia.org/wiki/Standard_deviation, standard deviation}
+of the last 64 rounds. The values provided by the callback function are
+logarithmic, this means that the real estimate numbers can be obtained by
+calculating 2 to the power of the given value (2average). From a
+statistics point of view this means that:
+
+@itemize @bullet
+@item 68% of the time the real size is included in the interval
+[(2average-stddev), 2]
+@item 95% of the time the real size is included in the interval
+[(2average-2*stddev, 2^average+2*stddev]
+@item 99.7% of the time the real size is included in the interval
+[(2average-3*stddev, 2average+3*stddev]
+@end itemize
+
+The expected standard variation for 64 rounds in a network of stable size
+is 0.2. Thus, we can say that normally:
+
+@itemize @bullet
+@item 68% of the time the real size is in the range [-13%, +15%]
+@item 95% of the time the real size is in the range [-24%, +32%]
+@item 99.7% of the time the real size is in the range [-34%, +52%]
+@end itemize
+
+As said in the introduction, we can be quite sure that usually the real
+size is between one third and three times the estimate. This can of
+course vary with network conditions.
+Thus, applications may want to also consider the provided standard
+deviation value, not only the average (in particular, if the standard
+veriation is very high, the average maybe meaningless: the network size is
+changing rapidly).
+
+@node Examples2
+@subsubsection Examples2
+
+@c %**end of header
+
+Let's close with a couple examples.
+
+@table @asis
+
+@item Average: 10, std dev: 1 Here the estimate would be
+2^10 = 1024 peers. @footnote{The range in which we can be 95% sure is:
+[2^8, 2^12] = [256, 4096]. We can be very (>99.7%) sure that the network
+is not a hundred peers and absolutely sure that it is not a million peers,
+but somewhere around a thousand.}
+
+@item Average 22, std dev: 0.2 Here the estimate would be
+2^22 = 4 Million peers. @footnote{The range in which we can be 99.7% sure
+is: [2^21.4, 2^22.6] = [2.8M, 6.3M]. We can be sure that the network size
+is around four million, with absolutely way of it being 1 million.}
+
+@end table
+
+To put this in perspective, if someone remembers the LHC Higgs boson
+results, were announced with "5 sigma" and "6 sigma" certainties. In this
+case a 5 sigma minimum would be 2 million and a 6 sigma minimum,
+1.8 million.
+
+@node The NSE Client-Service Protocol
+@subsection The NSE Client-Service Protocol
+
+@c %**end of header
+
+As with the API, the client-service protocol is very simple, only has 2
+different messages, defined in @code{src/nse/nse.h}:
+
+@itemize @bullet
+@item @code{GNUNET_MESSAGE_TYPE_NSE_START}@ This message has no parameters
+and is sent from the client to the service upon connection.
+@item @code{GNUNET_MESSAGE_TYPE_NSE_ESTIMATE}@ This message is sent from
+the service to the client for every new estimate and upon connection.
+Contains a timestamp for the estimate, the average and the standard
+deviation for the respective round.
+@end itemize
+
+When the @code{GNUNET_NSE_disconnect} API call is executed, the client
+simply disconnects from the service, with no message involved.
+
+@node The NSE Peer-to-Peer Protocol
+@subsection The NSE Peer-to-Peer Protocol
+
+@c %**end of header
+
+The NSE subsystem only has one message in the P2P protocol, the
+@code{GNUNET_MESSAGE_TYPE_NSE_P2P_FLOOD} message.
+
+This message key contents are the timestamp to identify the round
+(differences in system clocks may cause some peers to send messages way
+too early or way too late, so the timestamp allows other peers to
+identify such messages easily), the
+@uref{http://en.wikipedia.org/wiki/Proof-of-work_system, proof of work}
+used to make it difficult to mount a
+@uref{http://en.wikipedia.org/wiki/Sybil_attack, Sybil attack}, and the
+public key, which is used to verify the signature on the message.
+
+Every peer stores a message for the previous, current and next round. The
+messages for the previous and current round are given to peers that
+connect to us. The message for the next round is simply stored until our
+system clock advances to the next round. The message for the current round
+is what we are flooding the network with right now.
+At the beginning of each round the peer does the following:
+
+@itemize @bullet
+@item calculates his own distance to the target value
+@item creates, signs and stores the message for the current round (unless
+it has a better message in the "next round" slot which came early in the
+previous round)
+@item calculates, based on the stored round message (own or received) when
+to stard flooding it to its neighbors
+@end itemize
+
+Upon receiving a message the peer checks the validity of the message
+(round, proof of work, signature). The next action depends on the
+contents of the incoming message:
+
+@itemize @bullet
+@item if the message is worse than the current stored message, the peer
+sends the current message back immediately, to stop the other peer from
+spreading suboptimal results
+@item if the message is better than the current stored message, the peer
+stores the new message and calculates the new target time to start
+spreading it to its neighbors (excluding the one the message came from)
+@item if the message is for the previous round, it is compared to the
+message stored in the "previous round slot", which may then be updated
+@item if the message is for the next round, it is compared to the message
+stored in the "next round slot", which again may then be updated
+@end itemize
+
+Finally, when it comes to send the stored message for the current round to
+the neighbors there is a random delay added for each neighbor, to avoid
+traffic spikes and minimize cross-messages.
+
+@cindex HOSTLIST subsystem
+@cindex hostlist subsystem
+@node GNUnet's HOSTLIST subsystem
+@section GNUnet's HOSTLIST subsystem
+
+@c %**end of header
+
+Peers in the GNUnet overlay network need address information so that they
+can connect with other peers. GNUnet uses so called HELLO messages to
+store and exchange peer addresses.
+GNUnet provides several methods for peers to obtain this information:
+
+@itemize @bullet
+@item out-of-band exchange of HELLO messages (manually, using for example
+gnunet-peerinfo)
+@item HELLO messages shipped with GNUnet (automatic with distribution)
+@item UDP neighbor discovery in LAN (IPv4 broadcast, IPv6 multicast)
+@item topology gossiping (learning from other peers we already connected
+to), and
+@item the HOSTLIST daemon covered in this section, which is particularly
+relevant for bootstrapping new peers.
+@end itemize
+
+New peers have no existing connections (and thus cannot learn from gossip
+among peers), may not have other peers in their LAN and might be started
+with an outdated set of HELLO messages from the distribution.
+In this case, getting new peers to connect to the network requires either
+manual effort or the use of a HOSTLIST to obtain HELLOs.
+
+@menu
+* HELLOs::
+* Overview for the HOSTLIST subsystem::
+* Interacting with the HOSTLIST daemon::
+* Hostlist security address validation::
+* The HOSTLIST daemon::
+* The HOSTLIST server::
+* The HOSTLIST client::
+* Usage::
+@end menu
+
+@node HELLOs
+@subsection HELLOs
+
+@c %**end of header
+
+The basic information peers require to connect to other peers are
+contained in so called HELLO messages you can think of as a business card.
+Besides the identity of the peer (based on the cryptographic public key) a
+HELLO message may contain address information that specifies ways to
+contact a peer. By obtaining HELLO messages, a peer can learn how to
+contact other peers.
+
+@node Overview for the HOSTLIST subsystem
+@subsection Overview for the HOSTLIST subsystem
+
+@c %**end of header
+
+The HOSTLIST subsystem provides a way to distribute and obtain contact
+information to connect to other peers using a simple HTTP GET request.
+It's implementation is split in three parts, the main file for the daemon
+itself (@file{gnunet-daemon-hostlist.c}), the HTTP client used to download
+peer information (@file{hostlist-client.c}) and the server component used
+to provide this information to other peers (@file{hostlist-server.c}).
+The server is basically a small HTTP web server (based on GNU
+libmicrohttpd) which provides a list of HELLOs known to the local peer for
+download. The client component is basically a HTTP client
+(based on libcurl) which can download hostlists from one or more websites.
+The hostlist format is a binary blob containing a sequence of HELLO
+messages. Note that any HTTP server can theoretically serve a hostlist,
+the build-in hostlist server makes it simply convenient to offer this
+service.
+
+
+@menu
+* Features::
+* Limitations2::
+@end menu
+
+@node Features
+@subsubsection Features
+
+@c %**end of header
+
+The HOSTLIST daemon can:
+
+@itemize @bullet
+@item provide HELLO messages with validated addresses obtained from
+PEERINFO to download for other peers
+@item download HELLO messages and forward these message to the TRANSPORT
+subsystem for validation
+@item advertises the URL of this peer's hostlist address to other peers
+via gossip
+@item automatically learn about hostlist servers from the gossip of other
+peers
+@end itemize
+
+@node Limitations2
+@subsubsection Limitations2
+
+@c %**end of header
+
+The HOSTLIST daemon does not:
+
+@itemize @bullet
+@item verify the cryptographic information in the HELLO messages
+@item verify the address information in the HELLO messages
+@end itemize
+
+@node Interacting with the HOSTLIST daemon
+@subsection Interacting with the HOSTLIST daemon
+
+@c %**end of header
+
+The HOSTLIST subsystem is currently implemented as a daemon, so there is
+no need for the user to interact with it and therefore there is no
+command line tool and no API to communicate with the daemon. In the
+future, we can envision changing this to allow users to manually trigger
+the download of a hostlist.
+
+Since there is no command line interface to interact with HOSTLIST, the
+only way to interact with the hostlist is to use STATISTICS to obtain or
+modify information about the status of HOSTLIST:
+
+@example
+$ gnunet-statistics -s hostlist
+@end example
+
+@noindent
+In particular, HOSTLIST includes a @strong{persistent} value in statistics
+that specifies when the hostlist server might be queried next. As this
+value is exponentially increasing during runtime, developers may want to
+reset or manually adjust it. Note that HOSTLIST (but not STATISTICS) needs
+to be shutdown if changes to this value are to have any effect on the
+daemon (as HOSTLIST does not monitor STATISTICS for changes to the
+download frequency).
+
+@node Hostlist security address validation
+@subsection Hostlist security address validation
+
+@c %**end of header
+
+Since information obtained from other parties cannot be trusted without
+validation, we have to distinguish between @emph{validated} and
+@emph{not validated} addresses. Before using (and so trusting)
+information from other parties, this information has to be double-checked
+(validated). Address validation is not done by HOSTLIST but by the
+TRANSPORT service.
+
+The HOSTLIST component is functionally located between the PEERINFO and
+the TRANSPORT subsystem. When acting as a server, the daemon obtains valid
+(@emph{validated}) peer information (HELLO messages) from the PEERINFO
+service and provides it to other peers. When acting as a client, it
+contacts the HOSTLIST servers specified in the configuration, downloads
+the (unvalidated) list of HELLO messages and forwards these information
+to the TRANSPORT server to validate the addresses.
+
+@node The HOSTLIST daemon
+@subsection The HOSTLIST daemon
+
+@c %**end of header
+
+The hostlist daemon is the main component of the HOSTLIST subsystem. It is
+started by the ARM service and (if configured) starts the HOSTLIST client
+and server components.
+
+If the daemon provides a hostlist itself it can advertise it's own
+hostlist to other peers. To do so it sends a
+@code{GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT} message to other peers
+when they connect to this peer on the CORE level. This hostlist
+advertisement message contains the URL to access the HOSTLIST HTTP
+server of the sender. The daemon may also subscribe to this type of
+message from CORE service, and then forward these kind of message to the
+HOSTLIST client. The client then uses all available URLs to download peer
+information when necessary.
+
+When starting, the HOSTLIST daemon first connects to the CORE subsystem
+and if hostlist learning is enabled, registers a CORE handler to receive
+this kind of messages. Next it starts (if configured) the client and
+server. It passes pointers to CORE connect and disconnect and receive
+handlers where the client and server store their functions, so the daemon
+can notify them about CORE events.
+
+To clean up on shutdown, the daemon has a cleaning task, shutting down all
+subsystems and disconnecting from CORE.
+
+@node The HOSTLIST server
+@subsection The HOSTLIST server
+
+@c %**end of header
+
+The server provides a way for other peers to obtain HELLOs. Basically it
+is a small web server other peers can connect to and download a list of
+HELLOs using standard HTTP; it may also advertise the URL of the hostlist
+to other peers connecting on CORE level.
+
+
+@menu
+* The HTTP Server::
+* Advertising the URL::
+@end menu
+
+@node The HTTP Server
+@subsubsection The HTTP Server
+
+@c %**end of header
+
+During startup, the server starts a web server listening on the port
+specified with the HTTPPORT value (default 8080). In addition it connects
+to the PEERINFO service to obtain peer information. The HOSTLIST server
+uses the GNUNET_PEERINFO_iterate function to request HELLO information for
+all peers and adds their information to a new hostlist if they are
+suitable (expired addresses and HELLOs without addresses are both not
+suitable) and the maximum size for a hostlist is not exceeded
+(MAX_BYTES_PER_HOSTLISTS = 500000).
+When PEERINFO finishes (with a last NULL callback), the server destroys
+the previous hostlist response available for download on the web server
+and replaces it with the updated hostlist. The hostlist format is
+basically a sequence of HELLO messages (as obtained from PEERINFO) without
+any special tokenization. Since each HELLO message contains a size field,
+the response can easily be split into separate HELLO messages by the
+client.
+
+A HOSTLIST client connecting to the HOSTLIST server will receive the
+hostlist as a HTTP response and the the server will terminate the
+connection with the result code @code{HTTP 200 OK}.
+The connection will be closed immediately if no hostlist is available.
+
+@node Advertising the URL
+@subsubsection Advertising the URL
+
+@c %**end of header
+
+The server also advertises the URL to download the hostlist to other peers
+if hostlist advertisement is enabled.
+When a new peer connects and has hostlist learning enabled, the server
+sends a @code{GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT} message to this
+peer using the CORE service.
+
+@node The HOSTLIST client
+@subsection The HOSTLIST client
+
+@c %**end of header
+
+The client provides the functionality to download the list of HELLOs from
+a set of URLs.
+It performs a standard HTTP request to the URLs configured and learned
+from advertisement messages received from other peers. When a HELLO is
+downloaded, the HOSTLIST client forwards the HELLO to the TRANSPORT
+service for validation.
+
+The client supports two modes of operation:
+
+@itemize @bullet
+@item download of HELLOs (bootstrapping)
+@item learning of URLs
+@end itemize
+
+@menu
+* Bootstrapping::
+* Learning::
+@end menu
+
+@node Bootstrapping
+@subsubsection Bootstrapping
+
+@c %**end of header
+
+For bootstrapping, it schedules a task to download the hostlist from the
+set of known URLs.
+The downloads are only performed if the number of current
+connections is smaller than a minimum number of connections
+(at the moment 4).
+The interval between downloads increases exponentially; however, the
+exponential growth is limited if it becomes longer than an hour.
+At that point, the frequency growth is capped at
+(#number of connections * 1h).
+
+Once the decision has been taken to download HELLOs, the daemon chooses a
+random URL from the list of known URLs. URLs can be configured in the
+configuration or be learned from advertisement messages.
+The client uses a HTTP client library (libcurl) to initiate the download
+using the libcurl multi interface.
+Libcurl passes the data to the callback_download function which
+stores the data in a buffer if space is available and the maximum size for
+a hostlist download is not exceeded (MAX_BYTES_PER_HOSTLISTS = 500000).
+When a full HELLO was downloaded, the HOSTLIST client offers this
+HELLO message to the TRANSPORT service for validation.
+When the download is finished or failed, statistical information about the
+quality of this URL is updated.
+
+@cindex HOSTLIST learning
+@node Learning
+@subsubsection Learning
+
+@c %**end of header
+
+The client also manages hostlist advertisements from other peers. The
+HOSTLIST daemon forwards @code{GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT}
+messages to the client subsystem, which extracts the URL from the message.
+Next, a test of the newly obtained URL is performed by triggering a
+download from the new URL. If the URL works correctly, it is added to the
+list of working URLs.
+
+The size of the list of URLs is restricted, so if an additional server is
+added and the list is full, the URL with the worst quality ranking
+(determined through successful downloads and number of HELLOs e.g.) is
+discarded. During shutdown the list of URLs is saved to a file for
+persistance and loaded on startup. URLs from the configuration file are
+never discarded.
+
+@node Usage
+@subsection Usage
+
+@c %**end of header
+
+To start HOSTLIST by default, it has to be added to the DEFAULTSERVICES
+section for the ARM services. This is done in the default configuration.
+
+For more information on how to configure the HOSTLIST subsystem see the
+installation handbook:@
+Configuring the hostlist to bootstrap@
+Configuring your peer to provide a hostlist
+
+@cindex IDENTITY
+@cindex identity subsystem
+@node GNUnet's IDENTITY subsystem
+@section GNUnet's IDENTITY subsystem
+
+@c %**end of header
+
+Identities of "users" in GNUnet are called egos.
+Egos can be used as pseudonyms ("fake names") or be tied to an
+organization (for example, "GNU") or even the actual identity of a human.
+GNUnet users are expected to have many egos. They might have one tied to
+their real identity, some for organizations they manage, and more for
+different domains where they want to operate under a pseudonym.
+
+The IDENTITY service allows users to manage their egos. The identity
+service manages the private keys egos of the local user; it does not
+manage identities of other users (public keys). Public keys for other
+users need names to become manageable. GNUnet uses the
+@dfn{GNU Name System} (GNS) to give names to other users and manage their
+public keys securely. This chapter is about the IDENTITY service,
+which is about the management of private keys.
+
+On the network, an ego corresponds to an ECDSA key (over Curve25519,
+using RFC 6979, as required by GNS). Thus, users can perform actions
+under a particular ego by using (signing with) a particular private key.
+Other users can then confirm that the action was really performed by that
+ego by checking the signature against the respective public key.
+
+The IDENTITY service allows users to associate a human-readable name with
+each ego. This way, users can use names that will remind them of the
+purpose of a particular ego.
+The IDENTITY service will store the respective private keys and
+allows applications to access key information by name.
+Users can change the name that is locally (!) associated with an ego.
+Egos can also be deleted, which means that the private key will be removed
+and it thus will not be possible to perform actions with that ego in the
+future.
+
+Additionally, the IDENTITY subsystem can associate service functions with
+egos.
+For example, GNS requires the ego that should be used for the shorten
+zone. GNS will ask IDENTITY for an ego for the "gns-short" service.
+The IDENTITY service has a mapping of such service strings to the name of
+the ego that the user wants to use for this service, for example
+"my-short-zone-ego".
+
+Finally, the IDENTITY API provides access to a special ego, the
+anonymous ego. The anonymous ego is special in that its private key is not
+really private, but fixed and known to everyone.
+Thus, anyone can perform actions as anonymous. This can be useful as with
+this trick, code does not have to contain a special case to distinguish
+between anonymous and pseudonymous egos.
+
+@menu
+* libgnunetidentity::
+* The IDENTITY Client-Service Protocol::
+@end menu
+
+@cindex libgnunetidentity
+@node libgnunetidentity
+@subsection libgnunetidentity
+@c %**end of header
+
+
+@menu
+* Connecting to the service::
+* Operations on Egos::
+* The anonymous Ego::
+* Convenience API to lookup a single ego::
+* Associating egos with service functions::
+@end menu
+
+@node Connecting to the service
+@subsubsection Connecting to the service
+
+@c %**end of header
+
+First, typical clients connect to the identity service using
+@code{GNUNET_IDENTITY_connect}. This function takes a callback as a
+parameter.
+If the given callback parameter is non-null, it will be invoked to notify
+the application about the current state of the identities in the system.
+
+@itemize @bullet
+@item First, it will be invoked on all known egos at the time of the
+connection. For each ego, a handle to the ego and the user's name for the
+ego will be passed to the callback. Furthermore, a @code{void **} context
+argument will be provided which gives the client the opportunity to
+associate some state with the ego.
+@item Second, the callback will be invoked with NULL for the ego, the name
+and the context. This signals that the (initial) iteration over all egos
+has completed.
+@item Then, the callback will be invoked whenever something changes about
+an ego.
+If an ego is renamed, the callback is invoked with the ego handle of the
+ego that was renamed, and the new name. If an ego is deleted, the callback
+is invoked with the ego handle and a name of NULL. In the deletion case,
+the application should also release resources stored in the context.
+@item When the application destroys the connection to the identity service
+using @code{GNUNET_IDENTITY_disconnect}, the callback is again invoked
+with the ego and a name of NULL (equivalent to deletion of the egos).
+This should again be used to clean up the per-ego context.
+@end itemize
+
+The ego handle passed to the callback remains valid until the callback is
+invoked with a name of NULL, so it is safe to store a reference to the
+ego's handle.
+
+@node Operations on Egos
+@subsubsection Operations on Egos
+
+@c %**end of header
+
+Given an ego handle, the main operations are to get its associated private
+key using @code{GNUNET_IDENTITY_ego_get_private_key} or its associated
+public key using @code{GNUNET_IDENTITY_ego_get_public_key}.
+
+The other operations on egos are pretty straightforward.
+Using @code{GNUNET_IDENTITY_create}, an application can request the
+creation of an ego by specifying the desired name.
+The operation will fail if that name is
+already in use. Using @code{GNUNET_IDENTITY_rename} the name of an
+existing ego can be changed. Finally, egos can be deleted using
+@code{GNUNET_IDENTITY_delete}. All of these operations will trigger
+updates to the callback given to the @code{GNUNET_IDENTITY_connect}
+function of all applications that are connected with the identity service
+at the time. @code{GNUNET_IDENTITY_cancel} can be used to cancel the
+operations before the respective continuations would be called.
+It is not guaranteed that the operation will not be completed anyway,
+only the continuation will no longer be called.
+
+@node The anonymous Ego
+@subsubsection The anonymous Ego
+
+@c %**end of header
+
+A special way to obtain an ego handle is to call
+@code{GNUNET_IDENTITY_ego_get_anonymous}, which returns an ego for the
+"anonymous" user --- anyone knows and can get the private key for this
+user, so it is suitable for operations that are supposed to be anonymous
+but require signatures (for example, to avoid a special path in the code).
+The anonymous ego is always valid and accessing it does not require a
+connection to the identity service.
+
+@node Convenience API to lookup a single ego
+@subsubsection Convenience API to lookup a single ego
+
+
+As applications commonly simply have to lookup a single ego, there is a
+convenience API to do just that. Use @code{GNUNET_IDENTITY_ego_lookup} to
+lookup a single ego by name. Note that this is the user's name for the
+ego, not the service function. The resulting ego will be returned via a
+callback and will only be valid during that callback. The operation can
+be cancelled via @code{GNUNET_IDENTITY_ego_lookup_cancel}
+(cancellation is only legal before the callback is invoked).
+
+@node Associating egos with service functions
+@subsubsection Associating egos with service functions
+
+
+The @code{GNUNET_IDENTITY_set} function is used to associate a particular
+ego with a service function. The name used by the service and the ego are
+given as arguments.
+Afterwards, the service can use its name to lookup the associated ego
+using @code{GNUNET_IDENTITY_get}.
+
+@node The IDENTITY Client-Service Protocol
+@subsection The IDENTITY Client-Service Protocol
+
+@c %**end of header
+
+A client connecting to the identity service first sends a message with
+type
+@code{GNUNET_MESSAGE_TYPE_IDENTITY_START} to the service. After that, the
+client will receive information about changes to the egos by receiving
+messages of type @code{GNUNET_MESSAGE_TYPE_IDENTITY_UPDATE}.
+Those messages contain the private key of the ego and the user's name of
+the ego (or zero bytes for the name to indicate that the ego was deleted).
+A special bit @code{end_of_list} is used to indicate the end of the
+initial iteration over the identity service's egos.
+
+The client can trigger changes to the egos by sending @code{CREATE},
+@code{RENAME} or @code{DELETE} messages.
+The CREATE message contains the private key and the desired name.@
+The RENAME message contains the old name and the new name.@
+The DELETE message only needs to include the name of the ego to delete.@
+The service responds to each of these messages with a @code{RESULT_CODE}
+message which indicates success or error of the operation, and possibly
+a human-readable error message.
+
+Finally, the client can bind the name of a service function to an ego by
+sending a @code{SET_DEFAULT} message with the name of the service function
+and the private key of the ego.
+Such bindings can then be resolved using a @code{GET_DEFAULT} message,
+which includes the name of the service function. The identity service
+will respond to a GET_DEFAULT request with a SET_DEFAULT message
+containing the respective information, or with a RESULT_CODE to
+indicate an error.
+
+@cindex NAMESTORE
+@cindex namestore subsystem
+@node GNUnet's NAMESTORE Subsystem
+@section GNUnet's NAMESTORE Subsystem
+
+The NAMESTORE subsystem provides persistent storage for local GNS zone
+information. All local GNS zone information are managed by NAMESTORE. It
+provides both the functionality to administer local GNS information (e.g.
+delete and add records) as well as to retrieve GNS information (e.g to
+list name information in a client).
+NAMESTORE does only manage the persistent storage of zone information
+belonging to the user running the service: GNS information from other
+users obtained from the DHT are stored by the NAMECACHE subsystem.
+
+NAMESTORE uses a plugin-based database backend to store GNS information
+with good performance. Here sqlite, MySQL and PostgreSQL are supported
+database backends.
+NAMESTORE clients interact with the IDENTITY subsystem to obtain
+cryptographic information about zones based on egos as described with the
+IDENTITY subsystem, but internally NAMESTORE refers to zones using the
+ECDSA private key.
+In addition, it collaborates with the NAMECACHE subsystem and
+stores zone information when local information are modified in the
+GNS cache to increase look-up performance for local information.
+
+NAMESTORE provides functionality to look-up and store records, to iterate
+over a specific or all zones and to monitor zones for changes. NAMESTORE
+functionality can be accessed using the NAMESTORE api or the NAMESTORE
+command line tool.
+
+@menu
+* libgnunetnamestore::
+@end menu
+
+@cindex libgnunetnamestore
+@node libgnunetnamestore
+@subsection libgnunetnamestore
+
+To interact with NAMESTORE clients first connect to the NAMESTORE service
+using the @code{GNUNET_NAMESTORE_connect} passing a configuration handle.
+As a result they obtain a NAMESTORE handle, they can use for operations,
+or NULL is returned if the connection failed.
+
+To disconnect from NAMESTORE, clients use
+@code{GNUNET_NAMESTORE_disconnect} and specify the handle to disconnect.
+
+NAMESTORE internally uses the ECDSA private key to refer to zones. These
+private keys can be obtained from the IDENTITY subsytem.
+Here @emph{egos} @emph{can be used to refer to zones or the default ego
+assigned to the GNS subsystem can be used to obtained the master zone's
+private key.}
+
+
+@menu
+* Editing Zone Information::
+* Iterating Zone Information::
+* Monitoring Zone Information::
+@end menu
+
+@node Editing Zone Information
+@subsubsection Editing Zone Information
+
+@c %**end of header
+
+NAMESTORE provides functions to lookup records stored under a label in a
+zone and to store records under a label in a zone.
+
+To store (and delete) records, the client uses the
+@code{GNUNET_NAMESTORE_records_store} function and has to provide
+namestore handle to use, the private key of the zone, the label to store
+the records under, the records and number of records plus an callback
+function.
+After the operation is performed NAMESTORE will call the provided
+callback function with the result GNUNET_SYSERR on failure
+(including timeout/queue drop/failure to validate), GNUNET_NO if content
+was already there or not found GNUNET_YES (or other positive value) on
+success plus an additional error message.
+
+Records are deleted by using the store command with 0 records to store.
+It is important to note, that records are not merged when records exist
+with the label.
+So a client has first to retrieve records, merge with existing records
+and then store the result.
+
+To perform a lookup operation, the client uses the
+@code{GNUNET_NAMESTORE_records_store} function. Here he has to pass the
+namestore handle, the private key of the zone and the label. He also has
+to provide a callback function which will be called with the result of
+the lookup operation:
+the zone for the records, the label, and the records including the
+number of records included.
+
+A special operation is used to set the preferred nickname for a zone.
+This nickname is stored with the zone and is automatically merged with
+all labels and records stored in a zone. Here the client uses the
+@code{GNUNET_NAMESTORE_set_nick} function and passes the private key of
+the zone, the nickname as string plus a the callback with the result of
+the operation.
+
+@node Iterating Zone Information
+@subsubsection Iterating Zone Information
+
+@c %**end of header
+
+A client can iterate over all information in a zone or all zones managed
+by NAMESTORE.
+Here a client uses the @code{GNUNET_NAMESTORE_zone_iteration_start}
+function and passes the namestore handle, the zone to iterate over and a
+callback function to call with the result.
+If the client wants to iterate over all the, he passes NULL for the zone.
+A @code{GNUNET_NAMESTORE_ZoneIterator} handle is returned to be used to
+continue iteration.
+
+NAMESTORE calls the callback for every result and expects the client to
+call @code{GNUNET_NAMESTORE_zone_iterator_next} to continue to iterate or
+@code{GNUNET_NAMESTORE_zone_iterator_stop} to interrupt the iteration.
+When NAMESTORE reached the last item it will call the callback with a
+NULL value to indicate.
+
+@node Monitoring Zone Information
+@subsubsection Monitoring Zone Information
+
+@c %**end of header
+
+Clients can also monitor zones to be notified about changes. Here the
+clients uses the @code{GNUNET_NAMESTORE_zone_monitor_start} function and
+passes the private key of the zone and and a callback function to call
+with updates for a zone.
+The client can specify to obtain zone information first by iterating over
+the zone and specify a synchronization callback to be called when the
+client and the namestore are synced.
+
+On an update, NAMESTORE will call the callback with the private key of the
+zone, the label and the records and their number.
+
+To stop monitoring, the client calls
+@code{GNUNET_NAMESTORE_zone_monitor_stop} and passes the handle obtained
+from the function to start the monitoring.
+
+@cindex PEERINFO
+@cindex peerinfo subsystem
+@node GNUnet's PEERINFO subsystem
+@section GNUnet's PEERINFO subsystem
+
+@c %**end of header
+
+The PEERINFO subsystem is used to store verified (validated) information
+about known peers in a persistent way. It obtains these addresses for
+example from TRANSPORT service which is in charge of address validation.
+Validation means that the information in the HELLO message are checked by
+connecting to the addresses and performing a cryptographic handshake to
+authenticate the peer instance stating to be reachable with these
+addresses.
+Peerinfo does not validate the HELLO messages itself but only stores them
+and gives them to interested clients.
+
+As future work, we think about moving from storing just HELLO messages to
+providing a generic persistent per-peer information store.
+More and more subsystems tend to need to store per-peer information in
+persistent way.
+To not duplicate this functionality we plan to provide a PEERSTORE
+service providing this functionality.
+
+@menu
+* Features2::
+* Limitations3::
+* DeveloperPeer Information::
+* Startup::
+* Managing Information::
+* Obtaining Information::
+* The PEERINFO Client-Service Protocol::
+* libgnunetpeerinfo::
+@end menu
+
+@node Features2
+@subsection Features2
+
+@c %**end of header
+
+@itemize @bullet
+@item Persistent storage
+@item Client notification mechanism on update
+@item Periodic clean up for expired information
+@item Differentiation between public and friend-only HELLO
+@end itemize
+
+@node Limitations3
+@subsection Limitations3
+
+
+@itemize @bullet
+@item Does not perform HELLO validation
+@end itemize
+
+@node DeveloperPeer Information
+@subsection DeveloperPeer Information
+
+@c %**end of header
+
+The PEERINFO subsystem stores these information in the form of HELLO messages
+you can think of as business cards. These HELLO messages contain the public key
+of a peer and the addresses a peer can be reached under. The addresses include
+an expiration date describing how long they are valid. This information is
+updated regularly by the TRANSPORT service by revalidating the address. If an
+address is expired and not renewed, it can be removed from the HELLO message.
+
+Some peer do not want to have their HELLO messages distributed to other peers ,
+especially when GNUnet's friend-to-friend modus is enabled. To prevent this
+undesired distribution. PEERINFO distinguishes between @emph{public} and
+@emph{friend-only} HELLO messages. Public HELLO messages can be freely
+distributed to other (possibly unknown) peers (for example using the hostlist,
+gossiping, broadcasting), whereas friend-only HELLO messages may not be
+distributed to other peers. Friend-only HELLO messages have an additional flag
+@code{friend_only} set internally. For public HELLO message this flag is not
+set. PEERINFO does and cannot not check if a client is allowed to obtain a
+specific HELLO type.
+
+The HELLO messages can be managed using the GNUnet HELLO library. Other GNUnet
+systems can obtain these information from PEERINFO and use it for their
+purposes. Clients are for example the HOSTLIST component providing these
+information to other peers in form of a hostlist or the TRANSPORT subsystem
+using these information to maintain connections to other peers.
+
+@node Startup
+@subsection Startup
+
+@c %**end of header
+
+During startup the PEERINFO services loads persistent HELLOs from disk. First
+PEERINFO parses the directory configured in the HOSTS value of the
+@code{PEERINFO} configuration section to store PEERINFO information.@ For all
+files found in this directory valid HELLO messages are extracted. In addition
+it loads HELLO messages shipped with the GNUnet distribution. These HELLOs are
+used to simplify network bootstrapping by providing valid peer information with
+the distribution. The use of these HELLOs can be prevented by setting the
+@code{USE_INCLUDED_HELLOS} in the @code{PEERINFO} configuration section to
+@code{NO}. Files containing invalid information are removed.
+
+@node Managing Information
+@subsection Managing Information
+
+@c %**end of header
+
+The PEERINFO services stores information about known PEERS and a single HELLO
+message for every peer. A peer does not need to have a HELLO if no information
+are available. HELLO information from different sources, for example a HELLO
+obtained from a remote HOSTLIST and a second HELLO stored on disk, are combined
+and merged into one single HELLO message per peer which will be given to
+clients. During this merge process the HELLO is immediately written to disk to
+ensure persistence.
+
+PEERINFO in addition periodically scans the directory where information are
+stored for empty HELLO messages with expired TRANSPORT addresses.@ This
+periodic task scans all files in the directory and recreates the HELLO messages
+it finds. Expired TRANSPORT addresses are removed from the HELLO and if the
+HELLO does not contain any valid addresses, it is discarded and removed from
+disk.
+
+@node Obtaining Information
+@subsection Obtaining Information
+
+@c %**end of header
+
+When a client requests information from PEERINFO, PEERINFO performs a lookup
+for the respective peer or all peers if desired and transmits this information
+to the client. The client can specify if friend-only HELLOs have to be included
+or not and PEERINFO filters the respective HELLO messages before transmitting
+information.
+
+To notify clients about changes to PEERINFO information, PEERINFO maintains a
+list of clients interested in this notifications. Such a notification occurs if
+a HELLO for a peer was updated (due to a merge for example) or a new peer was
+added.
+
+@node The PEERINFO Client-Service Protocol
+@subsection The PEERINFO Client-Service Protocol
+
+@c %**end of header
+
+To connect and disconnect to and from the PEERINFO Service PEERINFO utilizes
+the util client/server infrastructure, so no special messages types are used
+here.
+
+To add information for a peer, the plain HELLO message is transmitted to the
+service without any wrapping. Alle information required are stored within the
+HELLO message. The PEERINFO service provides a message handler accepting and
+processing these HELLO messages.
+
+When obtaining PEERINFO information using the iterate functionality specific
+messages are used. To obtain information for all peers, a @code{struct
+ListAllPeersMessage} with message type
+@code{GNUNET_MESSAGE_TYPE_PEERINFO_GET_ALL} and a flag include_friend_only to
+indicate if friend-only HELLO messages should be included are transmitted. If
+information for a specific peer is required a @code{struct ListAllPeersMessage}
+with @code{GNUNET_MESSAGE_TYPE_PEERINFO_GET} containing the peer identity is
+used.
+
+For both variants the PEERINFO service replies for each HELLO message he wants
+to transmit with a @code{struct ListAllPeersMessage} with type
+@code{GNUNET_MESSAGE_TYPE_PEERINFO_INFO} containing the plain HELLO. The final
+message is @code{struct GNUNET_MessageHeader} with type
+@code{GNUNET_MESSAGE_TYPE_PEERINFO_INFO}. If the client receives this message,
+he can proceed with the next request if any is pending
+
+@node libgnunetpeerinfo
+@subsection libgnunetpeerinfo
+
+@c %**end of header
+
+The PEERINFO API consists mainly of three different functionalities:
+maintaining a connection to the service, adding new information and retrieving
+information form the PEERINFO service.
+
+
+@menu
+* Connecting to the Service::
+* Adding Information::
+* Obtaining Information2::
+@end menu
+
+@node Connecting to the Service
+@subsubsection Connecting to the Service
+
+@c %**end of header
+
+To connect to the PEERINFO service the function @code{GNUNET_PEERINFO_connect}
+is used, taking a configuration handle as an argument, and to disconnect from
+PEERINFO the function @code{GNUNET_PEERINFO_disconnect}, taking the PEERINFO
+handle returned from the connect function has to be called.
+
+@node Adding Information
+@subsubsection Adding Information
+
+@c %**end of header
+
+@code{GNUNET_PEERINFO_add_peer} adds a new peer to the PEERINFO subsystem
+storage. This function takes the PEERINFO handle as an argument, the HELLO
+message to store and a continuation with a closure to be called with the result
+of the operation. The @code{GNUNET_PEERINFO_add_peer} returns a handle to this
+operation allowing to cancel the operation with the respective cancel function
+@code{GNUNET_PEERINFO_add_peer_cancel}. To retrieve information from PEERINFO
+you can iterate over all information stored with PEERINFO or you can tell
+PEERINFO to notify if new peer information are available.
+
+@node Obtaining Information2
+@subsubsection Obtaining Information2
+
+@c %**end of header
+
+To iterate over information in PEERINFO you use @code{GNUNET_PEERINFO_iterate}.
+This function expects the PEERINFO handle, a flag if HELLO messages intended
+for friend only mode should be included, a timeout how long the operation
+should take and a callback with a callback closure to be called for the
+results. If you want to obtain information for a specific peer, you can specify
+the peer identity, if this identity is NULL, information for all peers are
+returned. The function returns a handle to allow to cancel the operation using
+@code{GNUNET_PEERINFO_iterate_cancel}.
+
+To get notified when peer information changes, you can use
+@code{GNUNET_PEERINFO_notify}. This function expects a configuration handle and
+a flag if friend-only HELLO messages should be included. The PEERINFO service
+will notify you about every change and the callback function will be called to
+notify you about changes. The function returns a handle to cancel notifications
+with @code{GNUNET_PEERINFO_notify_cancel}.
+
+
+@node GNUnet's PEERSTORE subsystem
+@section GNUnet's PEERSTORE subsystem
+
+@c %**end of header
+
+GNUnet's PEERSTORE subsystem offers persistent per-peer storage for other
+GNUnet subsystems. GNUnet subsystems can use PEERSTORE to persistently store
+and retrieve arbitrary data. Each data record stored with PEERSTORE contains
+the following fields:
+
+@itemize @bullet
+@item subsystem: Name of the subsystem responsible for the record.
+@item peerid: Identity of the peer this record is related to.
+@item key: a key string identifying the record.
+@item value: binary record value.
+@item expiry: record expiry date.
+@end itemize
+
+@menu
+* Functionality::
+* Architecture::
+* libgnunetpeerstore::
+@end menu
+
+@node Functionality
+@subsection Functionality
+
+@c %**end of header
+
+Subsystems can store any type of value under a (subsystem, peerid, key)
+combination. A "replace" flag set during store operations forces the PEERSTORE
+to replace any old values stored under the same (subsystem, peerid, key)
+combination with the new value. Additionally, an expiry date is set after which
+the record is *possibly* deleted by PEERSTORE.
+
+Subsystems can iterate over all values stored under any of the following
+combination of fields:
+
+@itemize @bullet
+@item (subsystem)
+@item (subsystem, peerid)
+@item (subsystem, key)
+@item (subsystem, peerid, key)
+@end itemize
+
+Subsystems can also request to be notified about any new values stored under a
+(subsystem, peerid, key) combination by sending a "watch" request to
+PEERSTORE.
+
+@node Architecture
+@subsection Architecture
+
+@c %**end of header
+
+PEERSTORE implements the following components:
+
+@itemize @bullet
+@item PEERSTORE service: Handles store, iterate and watch operations.
+@item PEERSTORE API: API to be used by other subsystems to communicate and
+issue commands to the PEERSTORE service.
+@item PEERSTORE plugins: Handles the persistent storage. At the moment, only an
+"sqlite" plugin is implemented.
+@end itemize
+
+@node libgnunetpeerstore
+@subsection libgnunetpeerstore
+
+@c %**end of header
+
+libgnunetpeerstore is the library containing the PEERSTORE API. Subsystems
+wishing to communicate with the PEERSTORE service use this API to open a
+connection to PEERSTORE. This is done by calling
+@code{GNUNET_PEERSTORE_connect} which returns a handle to the newly created
+connection. This handle has to be used with any further calls to the API.
+
+To store a new record, the function @code{GNUNET_PEERSTORE_store} is to be used
+which requires the record fields and a continuation function that will be
+called by the API after the STORE request is sent to the PEERSTORE service.
+Note that calling the continuation function does not mean that the record is
+successfully stored, only that the STORE request has been successfully sent to
+the PEERSTORE service. @code{GNUNET_PEERSTORE_store_cancel} can be called to
+cancel the STORE request only before the continuation function has been called.
+
+To iterate over stored records, the function @code{GNUNET_PEERSTORE_iterate} is
+to be used. @emph{peerid} and @emph{key} can be set to NULL. An iterator
+callback function will be called with each matching record found and a NULL
+record at the end to signal the end of result set.
+@code{GNUNET_PEERSTORE_iterate_cancel} can be used to cancel the ITERATE
+request before the iterator callback is called with a NULL record.
+
+To be notified with new values stored under a (subsystem, peerid, key)
+combination, the function @code{GNUNET_PEERSTORE_watch} is to be used. This
+will register the watcher with the PEERSTORE service, any new records matching
+the given combination will trigger the callback function passed to
+@code{GNUNET_PEERSTORE_watch}. This continues until
+@code{GNUNET_PEERSTORE_watch_cancel} is called or the connection to the service
+is destroyed.
+
+After the connection is no longer needed, the function
+@code{GNUNET_PEERSTORE_disconnect} can be called to disconnect from the
+PEERSTORE service. Any pending ITERATE or WATCH requests will be destroyed. If
+the @code{sync_first} flag is set to @code{GNUNET_YES}, the API will delay the
+disconnection until all pending STORE requests are sent to the PEERSTORE
+service, otherwise, the pending STORE requests will be destroyed as well.
+
+@node GNUnet's SET Subsystem
+@section GNUnet's SET Subsystem
+
+@c %**end of header
+
+The SET service implements efficient set operations between two peers over a
+mesh tunnel. Currently, set union and set intersection are the only supported
+operations. Elements of a set consist of an @emph{element type} and arbitrary
+binary @emph{data}. The size of an element's data is limited to around 62
+KB.
+
+@menu
+* Local Sets::
+* Set Modifications::
+* Set Operations::
+* Result Elements::
+* libgnunetset::
+* The SET Client-Service Protocol::
+* The SET Intersection Peer-to-Peer Protocol::
+* The SET Union Peer-to-Peer Protocol::
+@end menu
+
+@node Local Sets
+@subsection Local Sets
+
+@c %**end of header
+
+Sets created by a local client can be modified and reused for multiple
+operations. As each set operation requires potentially expensive special
+auxilliary data to be computed for each element of a set, a set can only
+participate in one type of set operation (i.e. union or intersection). The type
+of a set is determined upon its creation. If a the elements of a set are needed
+for an operation of a different type, all of the set's element must be copied
+to a new set of appropriate type.
+
+@node Set Modifications
+@subsection Set Modifications
+
+@c %**end of header
+
+Even when set operations are active, one can add to and remove elements from a
+set. However, these changes will only be visible to operations that have been
+created after the changes have taken place. That is, every set operation only
+sees a snapshot of the set from the time the operation was started. This
+mechanism is @emph{not} implemented by copying the whole set, but by attaching
+@emph{generation information} to each element and operation.
+
+@node Set Operations
+@subsection Set Operations
+
+@c %**end of header
+
+Set operations can be started in two ways: Either by accepting an operation
+request from a remote peer, or by requesting a set operation from a remote
+peer. Set operations are uniquely identified by the involved @emph{peers}, an
+@emph{application id} and the @emph{operation type}.
+
+The client is notified of incoming set operations by @emph{set listeners}. A
+set listener listens for incoming operations of a specific operation type and
+application id. Once notified of an incoming set request, the client can
+accept the set request (providing a local set for the operation) or reject
+it.
+
+@node Result Elements
+@subsection Result Elements
+
+@c %**end of header
+
+The SET service has three @emph{result modes} that determine how an operation's
+result set is delivered to the client:
+
+@itemize @bullet
+@item @strong{Full Result Set.} All elements of set resulting from the set
+operation are returned to the client.
+@item @strong{Added Elements.} Only elements that result from the operation and
+are not already in the local peer's set are returned. Note that for some
+operations (like set intersection) this result mode will never return any
+elements. This can be useful if only the remove peer is actually interested in
+the result of the set operation.
+@item @strong{Removed Elements.} Only elements that are in the local peer's
+initial set but not in the operation's result set are returned. Note that for
+some operations (like set union) this result mode will never return any
+elements. This can be useful if only the remove peer is actually interested in
+the result of the set operation.
+@end itemize
+
+@node libgnunetset
+@subsection libgnunetset
+
+@c %**end of header
+
+@menu
+* Sets::
+* Listeners::
+* Operations::
+* Supplying a Set::
+* The Result Callback::
+@end menu
+
+@node Sets
+@subsubsection Sets
+
+@c %**end of header
+
+New sets are created with @code{GNUNET_SET_create}. Both the local peer's
+configuration (as each set has its own client connection) and the operation
+type must be specified. The set exists until either the client calls
+@code{GNUNET_SET_destroy} or the client's connection to the service is
+disrupted. In the latter case, the client is notified by the return value of
+functions dealing with sets. This return value must always be checked.
+
+Elements are added and removed with @code{GNUNET_SET_add_element} and
+@code{GNUNET_SET_remove_element}.
+
+@node Listeners
+@subsubsection Listeners
+
+@c %**end of header
+
+Listeners are created with @code{GNUNET_SET_listen}. Each time time a remote
+peer suggests a set operation with an application id and operation type
+matching a listener, the listener's callack is invoked. The client then must
+synchronously call either @code{GNUNET_SET_accept} or @code{GNUNET_SET_reject}.
+Note that the operation will not be started until the client calls
+@code{GNUNET_SET_commit} (see Section "Supplying a Set").
+
+@node Operations
+@subsubsection Operations
+
+@c %**end of header
+
+Operations to be initiated by the local peer are created with
+@code{GNUNET_SET_prepare}. Note that the operation will not be started until
+the client calls @code{GNUNET_SET_commit} (see Section "Supplying a
+Set").
+
+@node Supplying a Set
+@subsubsection Supplying a Set
+
+@c %**end of header
+
+To create symmetry between the two ways of starting a set operation (accepting
+and nitiating it), the operation handles returned by @code{GNUNET_SET_accept}
+and @code{GNUNET_SET_prepare} do not yet have a set to operate on, thus they
+can not do any work yet.
+
+The client must call @code{GNUNET_SET_commit} to specify a set to use for an
+operation. @code{GNUNET_SET_commit} may only be called once per set
+operation.
+
+@node The Result Callback
+@subsubsection The Result Callback
+
+@c %**end of header
+
+Clients must specify both a result mode and a result callback with
+@code{GNUNET_SET_accept} and @code{GNUNET_SET_prepare}. The result callback
+with a status indicating either that an element was received, or the operation
+failed or succeeded. The interpretation of the received element depends on the
+result mode. The callback needs to know which result mode it is used in, as the
+arguments do not indicate if an element is part of the full result set, or if
+it is in the difference between the original set and the final set.
+
+@node The SET Client-Service Protocol
+@subsection The SET Client-Service Protocol
+
+@c %**end of header
+
+@menu
+* Creating Sets::
+* Listeners2::
+* Initiating Operations::
+* Modifying Sets::
+* Results and Operation Status::
+* Iterating Sets::
+@end menu
+
+@node Creating Sets
+@subsubsection Creating Sets
+
+@c %**end of header
+
+For each set of a client, there exists a client connection to the service. Sets
+are created by sending the @code{GNUNET_SERVICE_SET_CREATE} message over a new
+client connection. Multiple operations for one set are multiplexed over one
+client connection, using a request id supplied by the client.
+
+@node Listeners2
+@subsubsection Listeners2
+
+@c %**end of header
+
+Each listener also requires a seperate client connection. By sending the
+@code{GNUNET_SERVICE_SET_LISTEN} message, the client notifies the service of
+the application id and operation type it is interested in. A client rejects an
+incoming request by sending @code{GNUNET_SERVICE_SET_REJECT} on the listener's
+client connection. In contrast, when accepting an incoming request, a a
+@code{GNUNET_SERVICE_SET_ACCEPT} message must be sent over the@ set that is
+supplied for the set operation.
+
+@node Initiating Operations
+@subsubsection Initiating Operations
+
+@c %**end of header
+
+Operations with remote peers are initiated by sending a
+@code{GNUNET_SERVICE_SET_EVALUATE} message to the service. The@ client
+connection that this message is sent by determines the set to use.
+
+@node Modifying Sets
+@subsubsection Modifying Sets
+
+@c %**end of header
+
+Sets are modified with the @code{GNUNET_SERVICE_SET_ADD} and
+@code{GNUNET_SERVICE_SET_REMOVE} messages.
+
+
+@c %@menu
+@c %* Results and Operation Status::
+@c %* Iterating Sets::
+@c %@end menu
+
+@node Results and Operation Status
+@subsubsection Results and Operation Status
+@c %**end of header
+
+The service notifies the client of result elements and success/failure of a set
+operation with the @code{GNUNET_SERVICE_SET_RESULT} message.
+
+@node Iterating Sets
+@subsubsection Iterating Sets
+
+@c %**end of header
+
+All elements of a set can be requested by sending
+@code{GNUNET_SERVICE_SET_ITER_REQUEST}. The server responds with
+@code{GNUNET_SERVICE_SET_ITER_ELEMENT} and eventually terminates the iteration
+with @code{GNUNET_SERVICE_SET_ITER_DONE}. After each received element, the
+client@ must send @code{GNUNET_SERVICE_SET_ITER_ACK}. Note that only one set
+iteration may be active for a set at any given time.
+
+@node The SET Intersection Peer-to-Peer Protocol
+@subsection The SET Intersection Peer-to-Peer Protocol
+
+@c %**end of header
+
+The intersection protocol operates over CADET and starts with a
+GNUNET_MESSAGE_TYPE_SET_P2P_OPERATION_REQUEST being sent by the peer initiating
+the operation to the peer listening for inbound requests. It includes the
+number of elements of the initiating peer, which is used to decide which side
+will send a Bloom filter first.
+
+The listening peer checks if the operation type and application identifier are
+acceptable for its current state. If not, it responds with a
+GNUNET_MESSAGE_TYPE_SET_RESULT and a status of GNUNET_SET_STATUS_FAILURE (and
+terminates the CADET channel).
+
+If the application accepts the request, the listener sends back a@
+GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_ELEMENT_INFO if it has more elements
+in the set than the client. Otherwise, it immediately starts with the Bloom
+filter exchange. If the initiator receives a
+GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_ELEMENT_INFO response, it beings the
+Bloom filter exchange, unless the set size is indicated to be zero, in which
+case the intersection is considered finished after just the initial
+handshake.
+
+
+@menu
+* The Bloom filter exchange::
+* Salt::
+@end menu
+
+@node The Bloom filter exchange
+@subsubsection The Bloom filter exchange
+
+@c %**end of header
+
+In this phase, each peer transmits a Bloom filter over the remaining keys of
+the local set to the other peer using a
+GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_BF message. This message additionally
+includes the number of elements left in the sender's set, as well as the XOR
+over all of the keys in that set.
+
+The number of bits 'k' set per element in the Bloom filter is calculated based
+on the relative size of the two sets. Furthermore, the size of the Bloom filter
+is calculated based on 'k' and the number of elements in the set to maximize
+the amount of data filtered per byte transmitted on the wire (while avoiding an
+excessively high number of iterations).
+
+The receiver of the message removes all elements from its local set that do not
+pass the Bloom filter test. It then checks if the set size of the sender and
+the XOR over the keys match what is left of his own set. If they do, he sends
+a@ GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_DONE back to indicate that the
+latest set is the final result. Otherwise, the receiver starts another Bloom
+fitler exchange, except this time as the sender.
+
+@node Salt
+@subsubsection Salt
+
+@c %**end of header
+
+Bloomfilter operations are probablistic: With some non-zero probability the
+test may incorrectly say an element is in the set, even though it is not.
+
+To mitigate this problem, the intersection protocol iterates exchanging Bloom
+filters using a different random 32-bit salt in each iteration (the salt is
+also included in the message). With different salts, set operations may fail
+for different elements. Merging the results from the executions, the
+probability of failure drops to zero.
+
+The iterations terminate once both peers have established that they have sets
+of the same size, and where the XOR over all keys computes the same 512-bit
+value (leaving a failure probability of 2-511).
+
+@node The SET Union Peer-to-Peer Protocol
+@subsection The SET Union Peer-to-Peer Protocol
+
+@c %**end of header
+
+The SET union protocol is based on Eppstein's efficient set reconciliation
+without prior context. You should read this paper first if you want to
+understand the protocol.
+
+The union protocol operates over CADET and starts with a
+GNUNET_MESSAGE_TYPE_SET_P2P_OPERATION_REQUEST being sent by the peer initiating
+the operation to the peer listening for inbound requests. It includes the
+number of elements of the initiating peer, which is currently not used.
+
+The listening peer checks if the operation type and application identifier are
+acceptable for its current state. If not, it responds with a
+GNUNET_MESSAGE_TYPE_SET_RESULT and a status of GNUNET_SET_STATUS_FAILURE (and
+terminates the CADET channel).
+
+If the application accepts the request, it sends back a strata estimator using
+a message of type GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SE. The initiator evaluates
+the strata estimator and initiates the exchange of invertible Bloom filters,
+sending a GNUNET_MESSAGE_TYPE_SET_UNION_P2P_IBF.
+
+During the IBF exchange, if the receiver cannot invert the Bloom filter or
+detects a cycle, it sends a larger IBF in response (up to a defined maximum
+limit; if that limit is reached, the operation fails). Elements decoded while
+processing the IBF are transmitted to the other peer using
+GNUNET_MESSAGE_TYPE_SET_P2P_ELEMENTS, or requested from the other peer using
+GNUNET_MESSAGE_TYPE_SET_P2P_ELEMENT_REQUESTS messages, depending on the sign
+observed during decoding of the IBF. Peers respond to a
+GNUNET_MESSAGE_TYPE_SET_P2P_ELEMENT_REQUESTS message with the respective
+element in a GNUNET_MESSAGE_TYPE_SET_P2P_ELEMENTS message. If the IBF fully
+decodes, the peer responds with a GNUNET_MESSAGE_TYPE_SET_UNION_P2P_DONE
+message instead of another GNUNET_MESSAGE_TYPE_SET_UNION_P2P_IBF.
+
+All Bloom filter operations use a salt to mingle keys before hasing them into
+buckets, such that future iterations have a fresh chance of succeeding if they
+failed due to collisions before.
+
+@node GNUnet's STATISTICS subsystem
+@section GNUnet's STATISTICS subsystem
+
+@c %**end of header
+
+In GNUnet, the STATISTICS subsystem offers a central place for all subsystems
+to publish unsigned 64-bit integer run-time statistics. Keeping this
+information centrally means that there is a unified way for the user to obtain
+data on all subsystems, and individual subsystems do not have to always include
+a custom data export method for performance metrics and other statistics. For
+example, the TRANSPORT system uses STATISTICS to update information about the
+number of directly connected peers and the bandwidth that has been consumed by
+the various plugins. This information is valuable for diagnosing connectivity
+and performance issues.
+
+Following the GNUnet service architecture, the STATISTICS subsystem is divided
+into an API which is exposed through the header
+@strong{gnunet_statistics_service.h} and the STATISTICS service
+@strong{gnunet-service-statistics}. The @strong{gnunet-statistics} command-line
+tool can be used to obtain (and change) information about the values stored by
+the STATISTICS service. The STATISTICS service does not communicate with other
+peers.
+
+Data is stored in the STATISTICS service in the form of tuples
+@strong{(subsystem, name, value, persistence)}. The subsystem determines to
+which other GNUnet's subsystem the data belongs. name is the name through which
+value is associated. It uniquely identifies the record from among other records
+belonging to the same subsystem. In some parts of the code, the pair
+@strong{(subsystem, name)} is called a @strong{statistic} as it identifies the
+values stored in the STATISTCS service.The persistence flag determines if the
+record has to be preserved across service restarts. A record is said to be
+persistent if this flag is set for it; if not, the record is treated as a
+non-persistent record and it is lost after service restart. Persistent records
+are written to and read from the file @strong{statistics.data} before shutdown
+and upon startup. The file is located in the HOME directory of the peer.
+
+An anomaly of the STATISTICS service is that it does not terminate immediately
+upon receiving a shutdown signal if it has any clients connected to it. It
+waits for all the clients that are not monitors to close their connections
+before terminating itself. This is to prevent the loss of data during peer
+shutdown --- delaying the STATISTICS service shutdown helps other services to
+store important data to STATISTICS during shutdown.
+
+@menu
+* libgnunetstatistics::
+* The STATISTICS Client-Service Protocol::
+@end menu
+
+@node libgnunetstatistics
+@subsection libgnunetstatistics
+
+@c %**end of header
+
+@strong{libgnunetstatistics} is the library containing the API for the
+STATISTICS subsystem. Any process requiring to use STATISTICS should use this
+API by to open a connection to the STATISTICS service. This is done by calling
+the function @code{GNUNET_STATISTICS_create()}. This function takes the
+subsystem's name which is trying to use STATISTICS and a configuration. All
+values written to STATISTICS with this connection will be placed in the section
+corresponding to the given subsystem's name. The connection to STATISTICS can
+be destroyed with the function GNUNET_STATISTICS_destroy(). This function
+allows for the connection to be destroyed immediately or upon transferring all
+pending write requests to the service.
+
+Note: STATISTICS subsystem can be disabled by setting @code{DISABLE = YES}
+under the @code{[STATISTICS]} section in the configuration. With such a
+configuration all calls to @code{GNUNET_STATISTICS_create()} return @code{NULL}
+as the STATISTICS subsystem is unavailable and no other functions from the API
+can be used.
+
+
+@menu
+* Statistics retrieval::
+* Setting statistics and updating them::
+* Watches::
+@end menu
+
+@node Statistics retrieval
+@subsubsection Statistics retrieval
+
+@c %**end of header
+
+Once a connection to the statistics service is obtained, information about any
+other system which uses statistics can be retrieved with the function
+GNUNET_STATISTICS_get(). This function takes the connection handle, the name of
+the subsystem whose information we are interested in (a @code{NULL} value will
+retrieve information of all available subsystems using STATISTICS), the name of
+the statistic we are interested in (a @code{NULL} value will retrieve all
+available statistics), a continuation callback which is called when all of
+requested information is retrieved, an iterator callback which is called for
+each parameter in the retrieved information and a closure for the
+aforementioned callbacks. The library then invokes the iterator callback for
+each value matching the request.
+
+Call to @code{GNUNET_STATISTICS_get()} is asynchronous and can be canceled with
+the function @code{GNUNET_STATISTICS_get_cancel()}. This is helpful when
+retrieving statistics takes too long and especially when we want to shutdown
+and cleanup everything.
+
+@node Setting statistics and updating them
+@subsubsection Setting statistics and updating them
+
+@c %**end of header
+
+So far we have seen how to retrieve statistics, here we will learn how we can
+set statistics and update them so that other subsystems can retrieve them.
+
+A new statistic can be set using the function @code{GNUNET_STATISTICS_set()}.
+This function takes the name of the statistic and its value and a flag to make
+the statistic persistent. The value of the statistic should be of the type
+@code{uint64_t}. The function does not take the name of the subsystem; it is
+determined from the previous @code{GNUNET_STATISTICS_create()} invocation. If
+the given statistic is already present, its value is overwritten.
+
+An existing statistics can be updated, i.e its value can be increased or
+decreased by an amount with the function @code{GNUNET_STATISTICS_update()}. The
+parameters to this function are similar to @code{GNUNET_STATISTICS_set()},
+except that it takes the amount to be changed as a type @code{int64_t} instead
+of the value.
+
+The library will combine multiple set or update operations into one message if
+the client performs requests at a rate that is faster than the available IPC
+with the STATISTICS service. Thus, the client does not have to worry about
+sending requests too quickly.
+
+@node Watches
+@subsubsection Watches
+
+@c %**end of header
+
+As interesting feature of STATISTICS lies in serving notifications whenever a
+statistic of our interest is modified. This is achieved by registering a watch
+through the function @code{GNUNET_STATISTICS_watch()}. The parameters of this
+function are similar to those of @code{GNUNET_STATISTICS_get()}. Changes to the
+respective statistic's value will then cause the given iterator callback to be
+called. Note: A watch can only be registered for a specific statistic. Hence
+the subsystem name and the parameter name cannot be @code{NULL} in a call to
+@code{GNUNET_STATISTICS_watch()}.
+
+A registered watch will keep notifying any value changes until
+@code{GNUNET_STATISTICS_watch_cancel()} is called with the same parameters that
+are used for registering the watch.
+
+@node The STATISTICS Client-Service Protocol
+@subsection The STATISTICS Client-Service Protocol
+@c %**end of header
+
+
+@menu
+* Statistics retrieval2::
+* Setting and updating statistics::
+* Watching for updates::
+@end menu
+
+@node Statistics retrieval2
+@subsubsection Statistics retrieval2
+
+@c %**end of header
+
+To retrieve statistics, the client transmits a message of type
+@code{GNUNET_MESSAGE_TYPE_STATISTICS_GET} containing the given subsystem name
+and statistic parameter to the STATISTICS service. The service responds with a
+message of type @code{GNUNET_MESSAGE_TYPE_STATISTICS_VALUE} for each of the
+statistics parameters that match the client request for the client. The end of
+information retrieved is signaled by the service by sending a message of type
+@code{GNUNET_MESSAGE_TYPE_STATISTICS_END}.
+
+@node Setting and updating statistics
+@subsubsection Setting and updating statistics
+
+@c %**end of header
+
+The subsystem name, parameter name, its value and the persistence flag are
+communicated to the service through the message
+@code{GNUNET_MESSAGE_TYPE_STATISTICS_SET}.
+
+When the service receives a message of type
+@code{GNUNET_MESSAGE_TYPE_STATISTICS_SET}, it retrieves the subsystem name and
+checks for a statistic parameter with matching the name given in the message.
+If a statistic parameter is found, the value is overwritten by the new value
+from the message; if not found then a new statistic parameter is created with
+the given name and value.
+
+In addition to just setting an absolute value, it is possible to perform a
+relative update by sending a message of type
+@code{GNUNET_MESSAGE_TYPE_STATISTICS_SET} with an update flag
+(@code{GNUNET_STATISTICS_SETFLAG_RELATIVE}) signifying that the value in the
+message should be treated as an update value.
+
+@node Watching for updates
+@subsubsection Watching for updates
+
+@c %**end of header
+
+The function registers the watch at the service by sending a message of type
+@code{GNUNET_MESSAGE_TYPE_STATISTICS_WATCH}. The service then sends
+notifications through messages of type
+@code{GNUNET_MESSAGE_TYPE_STATISTICS_WATCH_VALUE} whenever the statistic
+parameter's value is changed.
+
+@node GNUnet's Distributed Hash Table (DHT)
+@section GNUnet's Distributed Hash Table (DHT)
+
+@c %**end of header
+
+GNUnet includes a generic distributed hash table that can be used by developers
+building P2P applications in the framework. This section documents high-level
+features and how developers are expected to use the DHT. We have a research
+paper detailing how the DHT works. Also, Nate's thesis includes a detailed
+description and performance analysis (in chapter 6).
+
+Key features of GNUnet's DHT include:
+
+@itemize @bullet
+@item stores key-value pairs with values up to (approximately) 63k in size
+@item works with many underlay network topologies (small-world, random graph),
+underlay does not need to be a full mesh / clique
+@item support for extended queries (more than just a simple 'key'), filtering
+duplicate replies within the network (bloomfilter) and content validation (for
+details, please read the subsection on the block library)
+@item can (optionally) return paths taken by the PUT and GET operations to the
+application
+@item provides content replication to handle churn
+@end itemize
+
+GNUnet's DHT is randomized and unreliable. Unreliable means that there is no
+strict guarantee that a value stored in the DHT is always found --- values are
+only found with high probability. While this is somewhat true in all P2P DHTs,
+GNUnet developers should be particularly wary of this fact (this will help you
+write secure, fault-tolerant code). Thus, when writing any application using
+the DHT, you should always consider the possibility that a value stored in the
+DHT by you or some other peer might simply not be returned, or returned with a
+significant delay. Your application logic must be written to tolerate this
+(naturally, some loss of performance or quality of service is expected in this
+case).
+
+@menu
+* Block library and plugins::
+* libgnunetdht::
+* The DHT Client-Service Protocol::
+* The DHT Peer-to-Peer Protocol::
+@end menu
+
+@node Block library and plugins
+@subsection Block library and plugins
+
+@c %**end of header
+
+@menu
+* What is a Block?::
+* The API of libgnunetblock::
+* Queries::
+* Sample Code::
+* Conclusion2::
+@end menu
+
+@node What is a Block?
+@subsubsection What is a Block?
+
+@c %**end of header
+
+Blocks are small (< 63k) pieces of data stored under a key (struct
+GNUNET_HashCode). Blocks have a type (enum GNUNET_BlockType) which defines
+their data format. Blocks are used in GNUnet as units of static data exchanged
+between peers and stored (or cached) locally. Uses of blocks include
+file-sharing (the files are broken up into blocks), the VPN (DNS information is
+stored in blocks) and the DHT (all information in the DHT and meta-information
+for the maintenance of the DHT are both stored using blocks). The block
+subsystem provides a few common functions that must be available for any type
+of block.
+
+@node The API of libgnunetblock
+@subsubsection The API of libgnunetblock
+
+@c %**end of header
+
+The block library requires for each (family of) block type(s) a block plugin
+(implementing gnunet_block_plugin.h) that provides basic functions that are
+needed by the DHT (and possibly other subsystems) to manage the block. These
+block plugins are typically implemented within their respective subsystems.@
+The main block library is then used to locate, load and query the appropriate
+block plugin. Which plugin is appropriate is determined by the block type
+(which is just a 32-bit integer). Block plugins contain code that specifies
+which block types are supported by a given plugin. The block library loads all
+block plugins that are installed at the local peer and forwards the application
+request to the respective plugin.
+
+The central functions of the block APIs (plugin and main library) are to allow
+the mapping of blocks to their respective key (if possible) and the ability to
+check that a block is well-formed and matches a given request (again, if
+possible). This way, GNUnet can avoid storing invalid blocks, storing blocks
+under the wrong key and forwarding blocks in response to a query that they do
+not answer.
+
+One key function of block plugins is that it allows GNUnet to detect duplicate
+replies (via the Bloom filter). All plugins MUST support detecting duplicate
+replies (by adding the current response to the Bloom filter and rejecting it if
+it is encountered again). If a plugin fails to do this, responses may loop in
+the network.
+
+@node Queries
+@subsubsection Queries
+@c %**end of header
+
+The query format for any block in GNUnet consists of four main components.
+First, the type of the desired block must be specified. Second, the query must
+contain a hash code. The hash code is used for lookups in hash tables and
+databases and must not be unique for the block (however, if possible a unique
+hash should be used as this would be best for performance). Third, an optional
+Bloom filter can be specified to exclude known results; replies that hash to
+the bits set in the Bloom filter are considered invalid. False-positives can be
+eliminated by sending the same query again with a different Bloom filter
+mutator value, which parameterizes the hash function that is used. Finally, an
+optional application-specific "eXtended query" (xquery) can be specified to
+further constrain the results. It is entirely up to the type-specific plugin to
+determine whether or not a given block matches a query (type, hash, Bloom
+filter, and xquery). Naturally, not all xquery's are valid and some types of
+blocks may not support Bloom filters either, so the plugin also needs to check
+if the query is valid in the first place.
+
+Depending on the results from the plugin, the DHT will then discard the
+(invalid) query, forward the query, discard the (invalid) reply, cache the
+(valid) reply, and/or forward the (valid and non-duplicate) reply.
+
+@node Sample Code
+@subsubsection Sample Code
+
+@c %**end of header
+
+The source code in @strong{plugin_block_test.c} is a good starting point for
+new block plugins --- it does the minimal work by implementing a plugin that
+performs no validation at all. The respective @strong{Makefile.am} shows how to
+build and install a block plugin.
+
+@node Conclusion2
+@subsubsection Conclusion2
+
+@c %**end of header
+
+In conclusion, GNUnet subsystems that want to use the DHT need to define a
+block format and write a plugin to match queries and replies. For testing, the
+"GNUNET_BLOCK_TYPE_TEST" block type can be used; it accepts any query as valid
+and any reply as matching any query. This type is also used for the DHT command
+line tools. However, it should NOT be used for normal applications due to the
+lack of error checking that results from this primitive implementation.
+
+@node libgnunetdht
+@subsection libgnunetdht
+
+@c %**end of header
+
+The DHT API itself is pretty simple and offers the usual GET and PUT functions
+that work as expected. The specified block type refers to the block library
+which allows the DHT to run application-specific logic for data stored in the
+network.
+
+
+@menu
+* GET::
+* PUT::
+* MONITOR::
+* DHT Routing Options::
+@end menu
+
+@node GET
+@subsubsection GET
+
+@c %**end of header
+
+When using GET, the main consideration for developers (other than the block
+library) should be that after issuing a GET, the DHT will continuously cause
+(small amounts of) network traffic until the operation is explicitly canceled.
+So GET does not simply send out a single network request once; instead, the
+DHT will continue to search for data. This is needed to achieve good success
+rates and also handles the case where the respective PUT operation happens
+after the GET operation was started. Developers should not cancel an existing
+GET operation and then explicitly re-start it to trigger a new round of
+network requests; this is simply inefficient, especially as the internal
+automated version can be more efficient, for example by filtering results in
+the network that have already been returned.
+
+If an application that performs a GET request has a set of replies that it
+already knows and would like to filter, it can call@
+@code{GNUNET_DHT_get_filter_known_results} with an array of hashes over the
+respective blocks to tell the DHT that these results are not desired (any
+more). This way, the DHT will filter the respective blocks using the block
+library in the network, which may result in a significant reduction in
+bandwidth consumption.
+
+@node PUT
+@subsubsection PUT
+
+@c %**end of header
+
+In contrast to GET operations, developers @strong{must} manually re-run PUT
+operations periodically (if they intend the content to continue to be
+available). Content stored in the DHT expires or might be lost due to churn.
+Furthermore, GNUnet's DHT typically requires multiple rounds of PUT operations
+before a key-value pair is consistently available to all peers (the DHT
+randomizes paths and thus storage locations, and only after multiple rounds of
+PUTs there will be a sufficient number of replicas in large DHTs). An explicit
+PUT operation using the DHT API will only cause network traffic once, so in
+order to ensure basic availability and resistance to churn (and adversaries),
+PUTs must be repeated. While the exact frequency depends on the application, a
+rule of thumb is that there should be at least a dozen PUT operations within
+the content lifetime. Content in the DHT typically expires after one day, so
+DHT PUT operations should be repeated at least every 1-2 hours.
+
+@node MONITOR
+@subsubsection MONITOR
+
+@c %**end of header
+
+The DHT API also allows applications to monitor messages crossing the local
+DHT service. The types of messages used by the DHT are GET, PUT and RESULT
+messages. Using the monitoring API, applications can choose to monitor these
+requests, possibly limiting themselves to requests for a particular block
+type.
+
+The monitoring API is not only usefu only for diagnostics, it can also be used
+to trigger application operations based on PUT operations. For example, an
+application may use PUTs to distribute work requests to other peers. The
+workers would then monitor for PUTs that give them work, instead of looking
+for work using GET operations. This can be beneficial, especially if the
+workers have no good way to guess the keys under which work would be stored.
+Naturally, additional protocols might be needed to ensure that the desired
+number of workers will process the distributed workload.
+
+@node DHT Routing Options
+@subsubsection DHT Routing Options
+
+@c %**end of header
+
+There are two important options for GET and PUT requests:
+
+@table @asis
+@item GNUNET_DHT_RO_DEMULITPLEX_EVERYWHERE This option means that all peers
+should process the request, even if their peer ID is not closest to the key.
+For a PUT request, this means that all peers that a request traverses may make
+a copy of the data. Similarly for a GET request, all peers will check their
+local database for a result. Setting this option can thus significantly improve
+caching and reduce bandwidth consumption --- at the expense of a larger DHT
+database. If in doubt, we recommend that this option should be used.
+@item GNUNET_DHT_RO_RECORD_ROUTE This option instructs the DHT to record the path
+that a GET or a PUT request is taking through the overlay network. The
+resulting paths are then returned to the application with the respective
+result. This allows the receiver of a result to construct a path to the
+originator of the data, which might then be used for routing. Naturally,
+setting this option requires additional bandwidth and disk space, so
+applications should only set this if the paths are needed by the application
+logic.
+@item GNUNET_DHT_RO_FIND_PEER This option is an internal option used by
+the DHT's peer discovery mechanism and should not be used by applications.
+@item GNUNET_DHT_RO_BART This option is currently not implemented. It may in
+the future offer performance improvements for clique topologies.
+@end table
+
+@node The DHT Client-Service Protocol
+@subsection The DHT Client-Service Protocol
+
+@c %**end of header
+
+@menu
+* PUTting data into the DHT::
+* GETting data from the DHT::
+* Monitoring the DHT::
+@end menu
+
+@node PUTting data into the DHT
+@subsubsection PUTting data into the DHT
+
+@c %**end of header
+
+To store (PUT) data into the DHT, the client sends a@ @code{struct
+GNUNET_DHT_ClientPutMessage} to the service. This message specifies the block
+type, routing options, the desired replication level, the expiration time, key,
+value and a 64-bit unique ID for the operation. The service responds with a@
+@code{struct GNUNET_DHT_ClientPutConfirmationMessage} with the same 64-bit
+unique ID. Note that the service sends the confirmation as soon as it has
+locally processed the PUT request. The PUT may still be propagating through the
+network at this time.
+
+In the future, we may want to change this to provide (limited) feedback to the
+client, for example if we detect that the PUT operation had no effect because
+the same key-value pair was already stored in the DHT. However, changing this
+would also require additional state and messages in the P2P
+interaction.
+
+@node GETting data from the DHT
+@subsubsection GETting data from the DHT
+
+@c %**end of header
+
+To retrieve (GET) data from the DHT, the client sends a@ @code{struct
+GNUNET_DHT_ClientGetMessage} to the service. The message specifies routing
+options, a replication level (for replicating the GET, not the content), the
+desired block type, the key, the (optional) extended query and unique 64-bit
+request ID.
+
+Additionally, the client may send any number of@ @code{struct
+GNUNET_DHT_ClientGetResultSeenMessage}s to notify the service about results
+that the client is already aware of. These messages consist of the key, the
+unique 64-bit ID of the request, and an arbitrary number of hash codes over the
+blocks that the client is already aware of. As messages are restricted to 64k,
+a client that already knows more than about a thousand blocks may need to send
+several of these messages. Naturally, the client should transmit these messages
+as quickly as possible after the original GET request such that the DHT can
+filter those results in the network early on. Naturally, as these messages are
+send after the original request, it is conceivalbe that the DHT service may
+return blocks that match those already known to the client anyway.
+
+In response to a GET request, the service will send @code{struct
+GNUNET_DHT_ClientResultMessage}s to the client. These messages contain the
+block type, expiration, key, unique ID of the request and of course the value
+(a block). Depending on the options set for the respective operations, the
+replies may also contain the path the GET and/or the PUT took through the
+network.
+
+A client can stop receiving replies either by disconnecting or by sending a
+@code{struct GNUNET_DHT_ClientGetStopMessage} which must contain the key and
+the 64-bit unique ID of the original request. Using an explicit "stop" message
+is more common as this allows a client to run many concurrent GET operations
+over the same connection with the DHT service --- and to stop them
+individually.
+
+@node Monitoring the DHT
+@subsubsection Monitoring the DHT
+
+@c %**end of header
+
+To begin monitoring, the client sends a @code{struct
+GNUNET_DHT_MonitorStartStop} message to the DHT service. In this message, flags
+can be set to enable (or disable) monitoring of GET, PUT and RESULT messages
+that pass through a peer. The message can also restrict monitoring to a
+particular block type or a particular key. Once monitoring is enabled, the DHT
+service will notify the client about any matching event using @code{struct
+GNUNET_DHT_MonitorGetMessage}s for GET events, @code{struct
+GNUNET_DHT_MonitorPutMessage} for PUT events and@ @code{struct
+GNUNET_DHT_MonitorGetRespMessage} for RESULTs. Each of these messages contains
+all of the information about the event.
+
+@node The DHT Peer-to-Peer Protocol
+@subsection The DHT Peer-to-Peer Protocol
+@c %**end of header
+
+
+@menu
+* Routing GETs or PUTs::
+* PUTting data into the DHT2::
+* GETting data from the DHT2::
+@end menu
+
+@node Routing GETs or PUTs
+@subsubsection Routing GETs or PUTs
+
+@c %**end of header
+
+When routing GETs or PUTs, the DHT service selects a suitable subset of
+neighbours for forwarding. The exact number of neighbours can be zero or more
+and depends on the hop counter of the query (initially zero) in relation to the
+(log of) the network size estimate, the desired replication level and the
+peer's connectivity. Depending on the hop counter and our network size
+estimate, the selection of the peers maybe randomized or by proximity to the
+key. Furthermore, requests include a set of peers that a request has already
+traversed; those peers are also excluded from the selection.
+
+@node PUTting data into the DHT2
+@subsubsection PUTting data into the DHT2
+
+@c %**end of header
+
+To PUT data into the DHT, the service sends a @code{struct PeerPutMessage} of
+type @code{GNUNET_MESSAGE_TYPE_DHT_P2P_PUT} to the respective neighbour. In
+addition to the usual information about the content (type, routing options,
+desired replication level for the content, expiration time, key and value), the
+message contains a fixed-size Bloom filter with information about which peers
+(may) have already seen this request. This Bloom filter is used to ensure that
+DHT messages never loop back to a peer that has already processed the request.
+Additionally, the message includes the current hop counter and, depending on
+the routing options, the message may include the full path that the message has
+taken so far. The Bloom filter should already contain the identity of the
+previous hop; however, the path should not include the identity of the previous
+hop and the receiver should append the identity of the sender to the path, not
+its own identity (this is done to reduce bandwidth).
+
+@node GETting data from the DHT2
+@subsubsection GETting data from the DHT2
+
+@c %**end of header
+
+A peer can search the DHT by sending @code{struct PeerGetMessage}s of type
+@code{GNUNET_MESSAGE_TYPE_DHT_P2P_GET} to other peers. In addition to the usual
+information about the request (type, routing options, desired replication level
+for the request, the key and the extended query), a GET request also again
+contains a hop counter, a Bloom filter over the peers that have processed the
+request already and depending on the routing options the full path traversed by
+the GET. Finally, a GET request includes a variable-size second Bloom filter
+and a so-called Bloom filter mutator value which together indicate which
+replies the sender has already seen. During the lookup, each block that matches
+they block type, key and extended query is additionally subjected to a test
+against this Bloom filter. The block plugin is expected to take the hash of the
+block and combine it with the mutator value and check if the result is not yet
+in the Bloom filter. The originator of the query will from time to time modify
+the mutator to (eventually) allow false-positives filtered by the Bloom filter
+to be returned.
+
+Peers that receive a GET request perform a local lookup (depending on their
+proximity to the key and the query options) and forward the request to other
+peers. They then remember the request (including the Bloom filter for blocking
+duplicate results) and when they obtain a matching, non-filtered response a
+@code{struct PeerResultMessage} of type@
+@code{GNUNET_MESSAGE_TYPE_DHT_P2P_RESULT} is forwarded to the previous hop.
+Whenver a result is forwarded, the block plugin is used to update the Bloom
+filter accordingly, to ensure that the same result is never forwarded more than
+once. The DHT service may also cache forwarded results locally if the
+"CACHE_RESULTS" option is set to "YES" in the configuration.
+
+@node The GNU Name System (GNS)
+@section The GNU Name System (GNS)
+
+@c %**end of header
+
+The GNU Name System (GNS) is a decentralized database that enables users to
+securely resolve names to values. Names can be used to identify other users
+(for example, in social networking), or network services (for example, VPN
+services running at a peer in GNUnet, or purely IP-based services on the
+Internet). Users interact with GNS by typing in a hostname that ends in ".gnu"
+or ".zkey".
+
+Videos giving an overview of most of the GNS and the motivations behind it is
+available here and here. The remainder of this chapter targets developers that
+are familiar with high level concepts of GNS as presented in these talks.
+
+GNS-aware applications should use the GNS resolver to obtain the respective
+records that are stored under that name in GNS. Each record consists of a type,
+value, expiration time and flags.
+
+The type specifies the format of the value. Types below 65536 correspond to DNS
+record types, larger values are used for GNS-specific records. Applications can
+define new GNS record types by reserving a number and implementing a plugin
+(which mostly needs to convert the binary value representation to a
+human-readable text format and vice-versa). The expiration time specifies how
+long the record is to be valid. The GNS API ensures that applications are only
+given non-expired values. The flags are typically irrelevant for applications,
+as GNS uses them internally to control visibility and validity of records.
+
+Records are stored along with a signature. The signature is generated using the
+private key of the authoritative zone. This allows any GNS resolver to verify
+the correctness of a name-value mapping.
+
+Internally, GNS uses the NAMECACHE to cache information obtained from other
+users, the NAMESTORE to store information specific to the local users, and the
+DHT to exchange data between users. A plugin API is used to enable applications
+to define new GNS record types.
+
+@menu
+* libgnunetgns::
+* libgnunetgnsrecord::
+* GNS plugins::
+* The GNS Client-Service Protocol::
+* Hijacking the DNS-Traffic using gnunet-service-dns::
+* Serving DNS lookups via GNS on W32::
+@end menu
+
+@node libgnunetgns
+@subsection libgnunetgns
+
+@c %**end of header
+
+The GNS API itself is extremely simple. Clients first connec to the GNS service
+using @code{GNUNET_GNS_connect}. They can then perform lookups using
+@code{GNUNET_GNS_lookup} or cancel pending lookups using
+@code{GNUNET_GNS_lookup_cancel}. Once finished, clients disconnect using
+@code{GNUNET_GNS_disconnect}.
+
+
+@menu
+* Looking up records::
+* Accessing the records::
+* Creating records::
+* Future work::
+@end menu
+
+@node Looking up records
+@subsubsection Looking up records
+
+@c %**end of header
+
+@code{GNUNET_GNS_lookup} takes a number of arguments:
+
+@table @asis
+@item handle This is simply the GNS connection handle from
+@code{GNUNET_GNS_connect}.
+@item name The client needs to specify the name to
+be resolved. This can be any valid DNS or GNS hostname.
+@item zone The client
+needs to specify the public key of the GNS zone against which the resolution
+should be done (the ".gnu" zone). Note that a key must be provided, even if the
+name ends in ".zkey". This should typically be the public key of the
+master-zone of the user.
+@item type This is the desired GNS or DNS record type
+to look for. While all records for the given name will be returned, this can be
+important if the client wants to resolve record types that themselves delegate
+resolution, such as CNAME, PKEY or GNS2DNS. Resolving a record of any of these
+types will only work if the respective record type is specified in the request,
+as the GNS resolver will otherwise follow the delegation and return the records
+from the respective destination, instead of the delegating record.
+@item only_cached This argument should typically be set to @code{GNUNET_NO}. Setting
+it to @code{GNUNET_YES} disables resolution via the overlay network.
+@item shorten_zone_key If GNS encounters new names during resolution, their
+respective zones can automatically be learned and added to the "shorten zone".
+If this is desired, clients must pass the private key of the shorten zone. If
+NULL is passed, shortening is disabled.
+@item proc This argument identifies
+the function to call with the result. It is given proc_cls, the number of
+records found (possilby zero) and the array of the records as arguments. proc
+will only be called once. After proc,> has been called, the lookup must no
+longer be cancelled.
+@item proc_cls The closure for proc.
+@end table
+
+@node Accessing the records
+@subsubsection Accessing the records
+
+@c %**end of header
+
+The @code{libgnunetgnsrecord} library provides an API to manipulate the GNS
+record array that is given to proc. In particular, it offers functions such as
+converting record values to human-readable strings (and back). However, most
+@code{libgnunetgnsrecord} functions are not interesting to GNS client
+applications.
+
+For DNS records, the @code{libgnunetdnsparser} library provides functions for
+parsing (and serializing) common types of DNS records.
+
+@node Creating records
+@subsubsection Creating records
+
+@c %**end of header
+
+Creating GNS records is typically done by building the respective record
+information (possibly with the help of @code{libgnunetgnsrecord} and
+@code{libgnunetdnsparser}) and then using the @code{libgnunetnamestore} to
+publish the information. The GNS API is not involved in this
+operation.
+
+@node Future work
+@subsubsection Future work
+
+@c %**end of header
+
+In the future, we want to expand @code{libgnunetgns} to allow applications to
+observe shortening operations performed during GNS resolution, for example so
+that users can receive visual feedback when this happens.
+
+@node libgnunetgnsrecord
+@subsection libgnunetgnsrecord
+
+@c %**end of header
+
+The @code{libgnunetgnsrecord} library is used to manipulate GNS records (in
+plaintext or in their encrypted format). Applications mostly interact with
+@code{libgnunetgnsrecord} by using the functions to convert GNS record values
+to strings or vice-versa, or to lookup a GNS record type number by name (or
+vice-versa). The library also provides various other functions that are mostly
+used internally within GNS, such as converting keys to names, checking for
+expiration, encrypting GNS records to GNS blocks, verifying GNS block
+signatures and decrypting GNS records from GNS blocks.
+
+We will now discuss the four commonly used functions of the API.@
+@code{libgnunetgnsrecord} does not perform these operations itself, but instead
+uses plugins to perform the operation. GNUnet includes plugins to support
+common DNS record types as well as standard GNS record types.
+
+
+@menu
+* Value handling::
+* Type handling::
+@end menu
+
+@node Value handling
+@subsubsection Value handling
+
+@c %**end of header
+
+@code{GNUNET_GNSRECORD_value_to_string} can be used to convert the (binary)
+representation of a GNS record value to a human readable, 0-terminated UTF-8
+string. NULL is returned if the specified record type is not supported by any
+available plugin.
+
+@code{GNUNET_GNSRECORD_string_to_value} can be used to try to convert a human
+readable string to the respective (binary) representation of a GNS record
+value.
+
+@node Type handling
+@subsubsection Type handling
+
+@c %**end of header
+
+@code{GNUNET_GNSRECORD_typename_to_number} can be used to obtain the numeric
+value associated with a given typename. For example, given the typename "A"
+(for DNS A reocrds), the function will return the number 1. A list of common
+DNS record types is
+@uref{http://en.wikipedia.org/wiki/List_of_DNS_record_types, here. Note that
+not all DNS record types are supported by GNUnet GNSRECORD plugins at this
+time.}
+
+@code{GNUNET_GNSRECORD_number_to_typename} can be used to obtain the typename
+associated with a given numeric value. For example, given the type number 1,
+the function will return the typename "A".
+
+@node GNS plugins
+@subsection GNS plugins
+
+@c %**end of header
+
+Adding a new GNS record type typically involves writing (or extending) a
+GNSRECORD plugin. The plugin needs to implement the
+@code{gnunet_gnsrecord_plugin.h} API which provides basic functions that are
+needed by GNSRECORD to convert typenames and values of the respective record
+type to strings (and back). These gnsrecord plugins are typically implemented
+within their respective subsystems. Examples for such plugins can be found in
+the GNSRECORD, GNS and CONVERSATION subsystems.
+
+The @code{libgnunetgnsrecord} library is then used to locate, load and query
+the appropriate gnsrecord plugin. Which plugin is appropriate is determined by
+the record type (which is just a 32-bit integer). The @code{libgnunetgnsrecord}
+library loads all block plugins that are installed at the local peer and
+forwards the application request to the plugins. If the record type is not
+supported by the plugin, it should simply return an error code.
+
+The central functions of the block APIs (plugin and main library) are the same
+four functions for converting between values and strings, and typenames and
+numbers documented in the previous subsection.
+
+@node The GNS Client-Service Protocol
+@subsection The GNS Client-Service Protocol
+
+@c %**end of header
+
+The GNS client-service protocol consists of two simple messages, the
+@code{LOOKUP} message and the @code{LOOKUP_RESULT}. Each @code{LOOKUP} message
+contains a unique 32-bit identifier, which will be included in the
+corresponding response. Thus, clients can send many lookup requests in parallel
+and receive responses out-of-order. A @code{LOOKUP} request also includes the
+public key of the GNS zone, the desired record type and fields specifying
+whether shortening is enabled or networking is disabled. Finally, the
+@code{LOOKUP} message includes the name to be resolved.
+
+The response includes the number of records and the records themselves in the
+format created by @code{GNUNET_GNSRECORD_records_serialize}. They can thus be
+deserialized using @code{GNUNET_GNSRECORD_records_deserialize}.
+
+@node Hijacking the DNS-Traffic using gnunet-service-dns
+@subsection Hijacking the DNS-Traffic using gnunet-service-dns
+
+@c %**end of header
+
+This section documents how the gnunet-service-dns (and the gnunet-helper-dns)
+intercepts DNS queries from the local system.@ This is merely one method for
+how we can obtain GNS queries. It is also possible to change @code{resolv.conf}
+to point to a machine running @code{gnunet-dns2gns} or to modify libc's name
+system switch (NSS) configuration to include a GNS resolution plugin. The
+method described in this chaper is more of a last-ditch catch-all approach.
+
+@code{gnunet-service-dns} enables intercepting DNS traffic using policy based
+routing. We MARK every outgoing DNS-packet if it was not sent by our
+application. Using a second routing table in the Linux kernel these marked
+packets are then routed through our virtual network interface and can thus be
+captured unchanged.
+
+Our application then reads the query and decides how to handle it: A query to
+an address ending in ".gnu" or ".zkey" is hijacked by @code{gnunet-service-gns}
+and resolved internally using GNS. In the future, a reverse query for an
+address of the configured virtual network could be answered with records kept
+about previous forward queries. Queries that are not hijacked by some
+application using the DNS service will be sent to the original recipient. The
+answer to the query will always be sent back through the virtual interface with
+the original nameserver as source address.
+
+
+@menu
+* Network Setup Details::
+@end menu
+
+@node Network Setup Details
+@subsubsection Network Setup Details
+
+@c %**end of header
+
+The DNS interceptor adds the following rules to the Linux kernel:
+@example
+iptables -t mangle -I OUTPUT 1 -p udp --sport $LOCALPORT --dport 53 -j
+ACCEPT iptables -t mangle -I OUTPUT 2 -p udp --dport 53 -j MARK --set-mark 3 ip
+rule add fwmark 3 table2 ip route add default via $VIRTUALDNS table2
+@end example
+
+Line 1 makes sure that all packets coming from a port our application opened
+beforehand (@code{$LOCALPORT}) will be routed normally. Line 2 marks every
+other packet to a DNS-Server with mark 3 (chosen arbitrarily). The third line
+adds a routing policy based on this mark 3 via the routing table.
+
+@node Serving DNS lookups via GNS on W32
+@subsection Serving DNS lookups via GNS on W32
+
+@c %**end of header
+
+This section documents how the libw32nsp (and gnunet-gns-helper-service-w32) do
+DNS resolutions of DNS queries on the local system. This only applies to GNUnet
+running on W32.
+
+W32 has a concept of "Namespaces" and "Namespace providers". These are used to
+present various name systems to applications in a generic way. Namespaces
+include DNS, mDNS, NLA and others. For each namespace any number of providers
+could be registered, and they are queried in an order of priority (which is
+adjustable).
+
+Applications can resolve names by using WSALookupService*() family of
+functions.
+
+However, these are WSA-only facilities. Common BSD socket functions for
+namespace resolutions are gethostbyname and getaddrinfo (among others). These
+functions are implemented internally (by default - by mswsock, which also
+implements the default DNS provider) as wrappers around WSALookupService*()
+functions (see "Sample Code for a Service Provider" on MSDN).
+
+On W32 GNUnet builds a libw32nsp - a namespace provider, which can then be
+installed into the system by using w32nsp-install (and uninstalled by
+w32nsp-uninstall), as described in "Installation Handbook".
+
+libw32nsp is very simple and has almost no dependencies. As a response to
+NSPLookupServiceBegin(), it only checks that the provider GUID passed to it by
+the caller matches GNUnet DNS Provider GUID, checks that name being resolved
+ends in ".gnu" or ".zkey", then connects to gnunet-gns-helper-service-w32 at
+127.0.0.1:5353 (hardcoded) and sends the name resolution request there,
+returning the connected socket to the caller.
+
+When the caller invokes NSPLookupServiceNext(), libw32nsp reads a completely
+formed reply from that socket, unmarshalls it, then gives it back to the
+caller.
+
+At the moment gnunet-gns-helper-service-w32 is implemented to ever give only
+one reply, and subsequent calls to NSPLookupServiceNext() will fail with
+WSA_NODATA (first call to NSPLookupServiceNext() might also fail if GNS failed
+to find the name, or there was an error connecting to it).
+
+gnunet-gns-helper-service-w32 does most of the processing:
+
+@itemize @bullet
+@item Maintains a connection to GNS.
+@item Reads GNS config and loads appropriate keys.
+@item Checks service GUID and decides on the type of record to look up,
+refusing to make a lookup outright when unsupported service GUID is passed.
+@item Launches the lookup
+@end itemize
+
+When lookup result arrives, gnunet-gns-helper-service-w32 forms a complete
+reply (including filling a WSAQUERYSETW structure and, possibly, a binary blob
+with a hostent structure for gethostbyname() client), marshalls it, and sends
+it back to libw32nsp. If no records were found, it sends an empty header.
+
+This works for most normal applications that use gethostbyname() or
+getaddrinfo() to resolve names, but fails to do anything with applications that
+use alternative means of resolving names (such as sending queries to a DNS
+server directly by themselves). This includes some of well known utilities,
+like "ping" and "nslookup".
+
+@node The GNS Namecache
+@section The GNS Namecache
+
+@c %**end of header
+
+The NAMECACHE subsystem is responsible for caching (encrypted) resolution
+results of the GNU Name System (GNS). GNS makes zone information available to
+other users via the DHT. However, as accessing the DHT for every lookup is
+expensive (and as the DHT's local cache is lost whenever the peer is
+restarted), GNS uses the NAMECACHE as a more persistent cache for DHT lookups.
+Thus, instead of always looking up every name in the DHT, GNS first checks if
+the result is already available locally in the NAMECACHE. Only if there is no
+result in the NAMECACHE, GNS queries the DHT. The NAMECACHE stores data in the
+same (encrypted) format as the DHT. It thus makes no sense to iterate over all
+items in the NAMECACHE --- the NAMECACHE does not have a way to provide the
+keys required to decrypt the entries.
+
+Blocks in the NAMECACHE share the same expiration mechanism as blocks in the
+DHT --- the block expires wheneever any of the records in the (encrypted) block
+expires. The expiration time of the block is the only information stored in
+plaintext. The NAMECACHE service internally performs all of the required work
+to expire blocks, clients do not have to worry about this. Also, given that
+NAMECACHE stores only GNS blocks that local users requested, there is no
+configuration option to limit the size of the NAMECACHE. It is assumed to be
+always small enough (a few MB) to fit on the drive.
+
+The NAMECACHE supports the use of different database backends via a plugin API.
+
+@menu
+* libgnunetnamecache::
+* The NAMECACHE Client-Service Protocol::
+* The NAMECACHE Plugin API::
+@end menu
+
+@node libgnunetnamecache
+@subsection libgnunetnamecache
+
+@c %**end of header
+
+The NAMECACHE API consists of five simple functions. First, there is
+@code{GNUNET_NAMECACHE_connect} to connect to the NAMECACHE service. This
+returns the handle required for all other operations on the NAMECACHE. Using
+@code{GNUNET_NAMECACHE_block_cache} clients can insert a block into the cache.
+@code{GNUNET_NAMECACHE_lookup_block} can be used to lookup blocks that were
+stored in the NAMECACHE. Both operations can be cancelled using
+@code{GNUNET_NAMECACHE_cancel}. Note that cancelling a
+@code{GNUNET_NAMECACHE_block_cache} operation can result in the block being
+stored in the NAMECACHE --- or not. Cancellation primarily ensures that the
+continuation function with the result of the operation will no longer be
+invoked. Finally, @code{GNUNET_NAMECACHE_disconnect} closes the connection to
+the NAMECACHE.
+
+The maximum size of a block that can be stored in the NAMECACHE is
+@code{GNUNET_NAMECACHE_MAX_VALUE_SIZE}, which is defined to be 63 kB.
+
+@node The NAMECACHE Client-Service Protocol
+@subsection The NAMECACHE Client-Service Protocol
+
+@c %**end of header
+
+All messages in the NAMECACHE IPC protocol start with the @code{struct
+GNUNET_NAMECACHE_Header} which adds a request ID (32-bit integer) to the
+standard message header. The request ID is used to match requests with the
+respective responses from the NAMECACHE, as they are allowed to happen
+out-of-order.
+
+
+@menu
+* Lookup::
+* Store::
+@end menu
+
+@node Lookup
+@subsubsection Lookup
+
+@c %**end of header
+
+The @code{struct LookupBlockMessage} is used to lookup a block stored in the
+cache. It contains the query hash. The NAMECACHE always responds with a
+@code{struct LookupBlockResponseMessage}. If the NAMECACHE has no response, it
+sets the expiration time in the response to zero. Otherwise, the response is
+expected to contain the expiration time, the ECDSA signature, the derived key
+and the (variable-size) encrypted data of the block.
+
+@node Store
+@subsubsection Store
+
+@c %**end of header
+
+The @code{struct BlockCacheMessage} is used to cache a block in the NAMECACHE.
+It has the same structure as the @code{struct LookupBlockResponseMessage}. The
+service responds with a @code{struct BlockCacheResponseMessage} which contains
+the result of the operation (success or failure). In the future, we might want
+to make it possible to provide an error message as well.
+
+@node The NAMECACHE Plugin API
+@subsection The NAMECACHE Plugin API
+@c %**end of header
+
+The NAMECACHE plugin API consists of two functions, @code{cache_block} to store
+a block in the database, and @code{lookup_block} to lookup a block in the
+database.
+
+
+@menu
+* Lookup2::
+* Store2::
+@end menu
+
+@node Lookup2
+@subsubsection Lookup2
+
+@c %**end of header
+
+The @code{lookup_block} function is expected to return at most one block to the
+iterator, and return @code{GNUNET_NO} if there were no non-expired results. If
+there are multiple non-expired results in the cache, the lookup is supposed to
+return the result with the largest expiration time.
+
+@node Store2
+@subsubsection Store2
+
+@c %**end of header
+
+The @code{cache_block} function is expected to try to store the block in the
+database, and return @code{GNUNET_SYSERR} if this was not possible for any
+reason. Furthermore, @code{cache_block} is expected to implicitly perform cache
+maintenance and purge blocks from the cache that have expired. Note that
+@code{cache_block} might encounter the case where the database already has
+another block stored under the same key. In this case, the plugin must ensure
+that the block with the larger expiration time is preserved. Obviously, this
+can done either by simply adding new blocks and selecting for the most recent
+expiration time during lookup, or by checking which block is more recent during
+the store operation.
+
+@node The REVOCATION Subsystem
+@section The REVOCATION Subsystem
+@c %**end of header
+
+The REVOCATION subsystem is responsible for key revocation of Egos. If a user
+learns that his private key has been compromised or has lost it, he can use the
+REVOCATION system to inform all of the other users that this private key is no
+longer valid. The subsystem thus includes ways to query for the validity of
+keys and to propagate revocation messages.
+
+@menu
+* Dissemination::
+* Revocation Message Design Requirements::
+* libgnunetrevocation::
+* The REVOCATION Client-Service Protocol::
+* The REVOCATION Peer-to-Peer Protocol::
+@end menu
+
+@node Dissemination
+@subsection Dissemination
+
+@c %**end of header
+
+When a revocation is performed, the revocation is first of all disseminated by
+flooding the overlay network. The goal is to reach every peer, so that when a
+peer needs to check if a key has been revoked, this will be purely a local
+operation where the peer looks at his local revocation list. Flooding the
+network is also the most robust form of key revocation --- an adversary would
+have to control a separator of the overlay graph to restrict the propagation of
+the revocation message. Flooding is also very easy to implement --- peers that
+receive a revocation message for a key that they have never seen before simply
+pass the message to all of their neighbours.
+
+Flooding can only distribute the revocation message to peers that are online.
+In order to notify peers that join the network later, the revocation service
+performs efficient set reconciliation over the sets of known revocation
+messages whenever two peers (that both support REVOCATION dissemination)
+connect. The SET service is used to perform this operation
+efficiently.
+
+@node Revocation Message Design Requirements
+@subsection Revocation Message Design Requirements
+
+@c %**end of header
+
+However, flooding is also quite costly, creating O(|E|) messages on a network
+with |E| edges. Thus, revocation messages are required to contain a
+proof-of-work, the result of an expensive computation (which, however, is cheap
+to verify). Only peers that have expended the CPU time necessary to provide
+this proof will be able to flood the network with the revocation message. This
+ensures that an attacker cannot simply flood the network with millions of
+revocation messages. The proof-of-work required by GNUnet is set to take days
+on a typical PC to compute; if the ability to quickly revoke a key is needed,
+users have the option to pre-compute revocation messages to store off-line and
+use instantly after their key has expired.
+
+Revocation messages must also be signed by the private key that is being
+revoked. Thus, they can only be created while the private key is in the
+possession of the respective user. This is another reason to create a
+revocation message ahead of time and store it in a secure location.
+
+@node libgnunetrevocation
+@subsection libgnunetrevocation
+
+@c %**end of header
+
+The REVOCATION API consists of two parts, to query and to issue
+revocations.
+
+
+@menu
+* Querying for revoked keys::
+* Preparing revocations::
+* Issuing revocations::
+@end menu
+
+@node Querying for revoked keys
+@subsubsection Querying for revoked keys
+
+@c %**end of header
+
+@code{GNUNET_REVOCATION_query} is used to check if a given ECDSA public key has
+been revoked. The given callback will be invoked with the result of the check.
+The query can be cancelled using @code{GNUNET_REVOCATION_query_cancel} on the
+return value.
+
+@node Preparing revocations
+@subsubsection Preparing revocations
+
+@c %**end of header
+
+It is often desirable to create a revocation record ahead-of-time and store it
+in an off-line location to be used later in an emergency. This is particularly
+true for GNUnet revocations, where performing the revocation operation itself
+is computationally expensive and thus is likely to take some time. Thus, if
+users want the ability to perform revocations quickly in an emergency, they
+must pre-compute the revocation message. The revocation API enables this with
+two functions that are used to compute the revocation message, but not trigger
+the actual revocation operation.
+
+@code{GNUNET_REVOCATION_check_pow} should be used to calculate the
+proof-of-work required in the revocation message. This function takes the
+public key, the required number of bits for the proof of work (which in GNUnet
+is a network-wide constant) and finally a proof-of-work number as arguments.
+The function then checks if the given proof-of-work number is a valid proof of
+work for the given public key. Clients preparing a revocation are expected to
+call this function repeatedly (typically with a monotonically increasing
+sequence of numbers of the proof-of-work number) until a given number satisfies
+the check. That number should then be saved for later use in the revocation
+operation.
+
+@code{GNUNET_REVOCATION_sign_revocation} is used to generate the signature that
+is required in a revocation message. It takes the private key that (possibly in
+the future) is to be revoked and returns the signature. The signature can again
+be saved to disk for later use, which will then allow performing a revocation
+even without access to the private key.
+
+@node Issuing revocations
+@subsubsection Issuing revocations
+
+
+Given a ECDSA public key, the signature from @code{GNUNET_REVOCATION_sign} and
+the proof-of-work, @code{GNUNET_REVOCATION_revoke} can be used to perform the
+actual revocation. The given callback is called upon completion of the
+operation. @code{GNUNET_REVOCATION_revoke_cancel} can be used to stop the
+library from calling the continuation; however, in that case it is undefined
+whether or not the revocation operation will be executed.
+
+@node The REVOCATION Client-Service Protocol
+@subsection The REVOCATION Client-Service Protocol
+
+
+The REVOCATION protocol consists of four simple messages.
+
+A @code{QueryMessage} containing a public ECDSA key is used to check if a
+particular key has been revoked. The service responds with a
+@code{QueryResponseMessage} which simply contains a bit that says if the given
+public key is still valid, or if it has been revoked.
+
+The second possible interaction is for a client to revoke a key by passing a
+@code{RevokeMessage} to the service. The @code{RevokeMessage} contains the
+ECDSA public key to be revoked, a signature by the corresponding private key
+and the proof-of-work, The service responds with a
+@code{RevocationResponseMessage} which can be used to indicate that the
+@code{RevokeMessage} was invalid (i.e. proof of work incorrect), or otherwise
+indicates that the revocation has been processed successfully.
+
+@node The REVOCATION Peer-to-Peer Protocol
+@subsection The REVOCATION Peer-to-Peer Protocol
+
+@c %**end of header
+
+Revocation uses two disjoint ways to spread revocation information among peers.
+First of all, P2P gossip exchanged via CORE-level neighbours is used to quickly
+spread revocations to all connected peers. Second, whenever two peers (that
+both support revocations) connect, the SET service is used to compute the union
+of the respective revocation sets.
+
+In both cases, the exchanged messages are @code{RevokeMessage}s which contain
+the public key that is being revoked, a matching ECDSA signature, and a
+proof-of-work. Whenever a peer learns about a new revocation this way, it first
+validates the signature and the proof-of-work, then stores it to disk
+(typically to a file $GNUNET_DATA_HOME/revocation.dat) and finally spreads the
+information to all directly connected neighbours.
+
+For computing the union using the SET service, the peer with the smaller hashed
+peer identity will connect (as a "client" in the two-party set protocol) to the
+other peer after one second (to reduce traffic spikes on connect) and initiate
+the computation of the set union. All revocation services use a common hash to
+identify the SET operation over revocation sets.
+
+The current implementation accepts revocation set union operations from all
+peers at any time; however, well-behaved peers should only initiate this
+operation once after establishing a connection to a peer with a larger hashed
+peer identity.
+
+@node GNUnet's File-sharing (FS) Subsystem
+@section GNUnet's File-sharing (FS) Subsystem
+
+@c %**end of header
+
+This chapter describes the details of how the file-sharing service works. As
+with all services, it is split into an API (libgnunetfs), the service process
+(gnunet-service-fs) and user interface(s). The file-sharing service uses the
+datastore service to store blocks and the DHT (and indirectly datacache) for
+lookups for non-anonymous file-sharing.@ Furthermore, the file-sharing service
+uses the block library (and the block fs plugin) for validation of DHT
+operations.
+
+In contrast to many other services, libgnunetfs is rather complex since the
+client library includes a large number of high-level abstractions; this is
+necessary since the Fs service itself largely only operates on the block level.
+The FS library is responsible for providing a file-based abstraction to
+applications, including directories, meta data, keyword search, verification,
+and so on.
+
+The method used by GNUnet to break large files into blocks and to use keyword
+search is called the "Encoding for Censorship Resistant Sharing" (ECRS). ECRS
+is largely implemented in the fs library; block validation is also reflected in
+the block FS plugin and the FS service. ECRS on-demand encoding is implemented
+in the FS service.
+
+NOTE: The documentation in this chapter is quite incomplete.
+
+@menu
+* Encoding for Censorship-Resistant Sharing (ECRS)::
+* File-sharing persistence directory structure::
+@end menu
+
+@node Encoding for Censorship-Resistant Sharing (ECRS)
+@subsection Encoding for Censorship-Resistant Sharing (ECRS)
+
+@c %**end of header
+
+When GNUnet shares files, it uses a content encoding that is called ECRS, the
+Encoding for Censorship-Resistant Sharing. Most of ECRS is described in the
+(so far unpublished) research paper attached to this page. ECRS obsoletes the
+previous ESED and ESED II encodings which were used in GNUnet before version
+0.7.0.@ @ The rest of this page assumes that the reader is familiar with the
+attached paper. What follows is a description of some minor extensions that
+GNUnet makes over what is described in the paper. The reason why these
+extensions are not in the paper is that we felt that they were obvious or
+trivial extensions to the original scheme and thus did not warrant space in
+the research report.
+
+
+@menu
+* Namespace Advertisements::
+* KSBlocks::
+@end menu
+
+@node Namespace Advertisements
+@subsubsection Namespace Advertisements
+
+@c %**end of header
+@c %**FIXME: all zeroses -> ?
+
+An @code{SBlock} with identifier all zeros is a signed
+advertisement for a namespace. This special @code{SBlock} contains metadata
+describing the content of the namespace. Instead of the name of the identifier
+for a potential update, it contains the identifier for the root of the
+namespace. The URI should always be empty. The @code{SBlock} is signed with
+the content provder's RSA private key (just like any other SBlock). Peers
+can search for @code{SBlock}s in order to find out more about a namespace.
+
+@node KSBlocks
+@subsubsection KSBlocks
+
+@c %**end of header
+
+GNUnet implements @code{KSBlocks} which are @code{KBlocks} that, instead of
+encrypting a CHK and metadata, encrypt an @code{SBlock} instead. In other
+words, @code{KSBlocks} enable GNUnet to find @code{SBlocks} using the global
+keyword search. Usually the encrypted @code{SBlock} is a namespace
+advertisement. The rationale behind @code{KSBlock}s and @code{SBlock}s is to
+enable peers to discover namespaces via keyword searches, and, to associate
+useful information with namespaces. When GNUnet finds @code{KSBlocks} during a
+normal keyword search, it adds the information to an internal list of
+discovered namespaces. Users looking for interesting namespaces can then
+inspect this list, reducing the need for out-of-band discovery of namespaces.
+Naturally, namespaces (or more specifically, namespace advertisements) can
+also be referenced from directories, but @code{KSBlock}s should make it easier
+to advertise namespaces for the owner of the pseudonym since they eliminate
+the need to first create a directory.
+
+Collections are also advertised using @code{KSBlock}s.
+
+@table @asis
+@item Attachment Size
+@item ecrs.pdf 270.68 KB
+@item https://gnunet.org/sites/default/files/ecrs.pdf
+@end table
+
+@node File-sharing persistence directory structure
+@subsection File-sharing persistence directory structure
+
+@c %**end of header
+
+This section documents how the file-sharing library implements persistence of
+file-sharing operations and specifically the resulting directory structure.
+This code is only active if the @code{GNUNET_FS_FLAGS_PERSISTENCE} flag was set
+when calling @code{GNUNET_FS_start}. In this case, the file-sharing library
+will try hard to ensure that all major operations (searching, downloading,
+publishing, unindexing) are persistent, that is, can live longer than the
+process itself. More specifically, an operation is supposed to live until it is
+explicitly stopped.
+
+If @code{GNUNET_FS_stop} is called before an operation has been stopped, a
+@code{SUSPEND} event is generated and then when the process calls
+@code{GNUNET_FS_start} next time, a @code{RESUME} event is generated.
+Additionally, even if an application crashes (segfault, SIGKILL, system crash)
+and hence @code{GNUNET_FS_stop} is never called and no @code{SUSPEND} events
+are generated, operations are still resumed (with @code{RESUME} events). This
+is implemented by constantly writing the current state of the file-sharing
+operations to disk. Specifically, the current state is always written to disk
+whenever anything significant changes (the exception are block-wise progress in
+publishing and unindexing, since those operations would be slowed down
+significantly and can be resumed cheaply even without detailed accounting).
+Note that@ if the process crashes (or is killed) during a serialization
+operation, FS does not guarantee that this specific operation is recoverable
+(no strict transactional semantics, again for performance reasons). However,
+all other unrelated operations should resume nicely.
+
+Since we need to serialize the state continuously and want to recover as much
+as possible even after crashing during a serialization operation, we do not use
+one large file for serialization. Instead, several directories are used for the
+various operations. When @code{GNUNET_FS_start} executes, the master
+directories are scanned for files describing operations to resume. Sometimes,
+these operations can refer to related operations in child directories which may
+also be resumed at this point. Note that corrupted files are cleaned up
+automatically. However, dangling files in child directories (those that are not
+referenced by files from the master directories) are not automatically removed.
+
+Persistence data is kept in a directory that begins with the "STATE_DIR" prefix
+from the configuration file (by default, "$SERVICEHOME/persistence/") followed
+by the name of the client as given to @code{GNUNET_FS_start} (for example,
+"gnunet-gtk") followed by the actual name of the master or child directory.
+
+The names for the master directories follow the names of the operations:
+
+@itemize @bullet
+@item "search"
+@item "download"
+@item "publish"
+@item "unindex"
+@end itemize
+
+Each of the master directories contains names (chosen at random) for each
+active top-level (master) operation.
+Note that a download that is associated with a search result is not a
+top-level operation.
+
+In contrast to the master directories, the child directories are only
+consulted when another operation refers to them.
+For each search, a subdirectory (named after the master search
+synchronization file) contains the search results.
+Search results can have an associated download, which is then stored in
+the general "download-child" directory.
+Downloads can be recursive, in which case children are stored in
+subdirectories mirroring the structure of the recursive download
+(either starting in the master "download" directory or in the
+"download-child" directory depending on how the download was initiated).
+For publishing operations, the "publish-file" directory contains
+information about the individual files and directories that are part of
+the publication.
+However, this directory structure is flat and does not mirror the
+structure of the publishing operation.
+Note that unindex operations cannot have associated child operations.
+
+@cindex REGEX subsystem
+@cindex regex subsystem
+@node GNUnet's REGEX Subsystem
+@section GNUnet's REGEX Subsystem
+
+@c %**end of header
+
+Using the REGEX subsystem, you can discover peers that offer a particular
+service using regular expressions.
+The peers that offer a service specify it using a regular expressions.
+Peers that want to patronize a service search using a string.
+The REGEX subsystem will then use the DHT to return a set of matching
+offerers to the patrons.
+
+For the technical details, we have Max's defense talk and Max's Master's
+thesis.
+
+@c An additional publication is under preparation and available to
+@c team members (in Git).
+@c FIXME: Where is the file? Point to it. Assuming that it's szengel2012ms
+
+@menu
+* How to run the regex profiler::
+@end menu
+
+@node How to run the regex profiler
+@subsection How to run the regex profiler
+
+@c %**end of header
+
+The gnunet-regex-profiler can be used to profile the usage of mesh/regex
+for a given set of regular expressions and strings.
+Mesh/regex allows you to announce your peer ID under a certain regex and
+search for peers matching a particular regex using a string.
+See @uref{https://gnunet.org/szengel2012ms, szengel2012ms} for a full
+introduction.
+
+First of all, the regex profiler uses GNUnet testbed, thus all the
+implications for testbed also apply to the regex profiler
+(for example you need password-less ssh login to the machines listed in
+your hosts file).
+
+@strong{Configuration}
+
+Moreover, an appropriate configuration file is needed.
+Generally you can refer to the
+@file{contrib/regex_profiler_infiniband.conf} file in the sourcecode
+of GNUnet for an example configuration.
+In the following paragraph the important details are highlighted.
+
+Announcing of the regular expressions is done by the
+gnunet-daemon-regexprofiler, therefore you have to make sure it is
+started, by adding it to the AUTOSTART set of ARM:
+
+@example
+[regexprofiler]
+AUTOSTART = YES
+@end example
+
+@noindent
+Furthermore you have to specify the location of the binary:
+
+@example
+[regexprofiler]
+# Location of the gnunet-daemon-regexprofiler binary.
+BINARY = /home/szengel/gnunet/src/mesh/.libs/gnunet-daemon-regexprofiler
+# Regex prefix that will be applied to all regular expressions and
+# search string.
+REGEX_PREFIX = "GNVPN-0001-PAD"
+@end example
+
+@noindent
+When running the profiler with a large scale deployment, you probably
+want to reduce the workload of each peer.
+Use the following options to do this.
+
+@example
+[dht]
+# Force network size estimation
+FORCE_NSE = 1
+
+[dhtcache]
+DATABASE = heap
+# Disable RC-file for Bloom filter? (for benchmarking with limited IO
+# availability)
+DISABLE_BF_RC = YES
+# Disable Bloom filter entirely
+DISABLE_BF = YES
+
+[nse]
+# Minimize proof-of-work CPU consumption by NSE
+WORKBITS = 1
+@end example
+
+@noindent
+@strong{Options}
+
+To finally run the profiler some options and the input data need to be
+specified on the command line.
+
+@example
+gnunet-regex-profiler -c config-file -d log-file -n num-links \
+-p path-compression-length -s search-delay -t matching-timeout \
+-a num-search-strings hosts-file policy-dir search-strings-file
+@end example
+
+@noindent
+Where...
+
+@itemize @bullet
+@item ... @code{config-file} means the configuration file created earlier.
+@item ... @code{log-file} is the file where to write statistics output.
+@item ... @code{num-links} indicates the number of random links between
+started peers.
+@item ... @code{path-compression-length} is the maximum path compression
+length in the DFA.
+@item ... @code{search-delay} time to wait between peers finished linking
+and starting to match strings.
+@item ... @code{matching-timeout} timeout after which to cancel the
+searching.
+@item ... @code{num-search-strings} number of strings in the
+search-strings-file.
+@item ... the @code{hosts-file} should contain a list of hosts for the
+testbed, one per line in the following format:
+
+@itemize @bullet
+@item @code{user@@host_ip:port}
+@end itemize
+@item ... the @code{policy-dir} is a folder containing text files
+containing one or more regular expressions. A peer is started for each
+file in that folder and the regular expressions in the corresponding file
+are announced by this peer.
+@item ... the @code{search-strings-file} is a text file containing search
+strings, one in each line.
+@end itemize
+
+@noindent
+You can create regular expressions and search strings for every AS in the
+Internet using the attached scripts. You need one of the
+@uref{http://data.caida.org/datasets/routing/routeviews-prefix2as/, CAIDA
+routeviews prefix2as} data files for this. Run
+
+@example
+create_regex.py <filename> <output path>
+@end example
+
+@noindent
+to create the regular expressions and
+
+@example
+create_strings.py <input path> <outfile>
+@end example
+
+@noindent
+to create a search strings file from the previously created
+regular expressions.
--- /dev/null
+@node GNUnet Installation Handbook
+@chapter GNUnet Installation Handbook
+
+This handbook describes how to install (build setup, compilation) and
+setup (configuration, start) GNUnet 0.10.x. After following these
+instructions you should be able to install and then start user-interfaces
+to interact with the network.
+
+This manual is far from complete, and we welcome informed contributions,
+be it in the form of new chapters or insightful comments.
+
+@menu
+* Dependencies::
+* Pre-installation notes::
+* Generic installation instructions::
+* Build instructions for Ubuntu 12.04 using Git::
+* Build Instructions for Microsoft Windows Platforms::
+* Build instructions for Debian 7.5::
+* Installing GNUnet from Git on Ubuntu 14.4::
+* Build instructions for Debian 8::
+* Outdated build instructions for previous revisions::
+* Portable GNUnet::
+* The graphical configuration interface::
+* How to start and stop a GNUnet peer::
+@end menu
+
+@node Dependencies
+@section Dependencies
+@c %**end of header
+
+This section lists the various known dependencies for
+GNUnet @value{EDITION}.
+Suggestions for missing dependencies or wrong version numbers are welcome.
+
+@menu
+* External dependencies::
+* Fixing libgnurl build issues::
+* Optional dependencies::
+* Internal dependencies::
+@end menu
+
+@node External dependencies
+@subsection External dependencies
+@c %**end of header
+
+These packages must be installed before a typical GNUnet installation
+can be performed:
+
+@itemize @bullet
+@item autoconf
+@item automake
+@item pkg-config
+@item libltdl
+@item gstreamer
+@item gst-plugins-base
+@item perl
+@item python (only 2.7 supported)@footnote{tests and gnunet-qr}
+@item jansson
+@item nss
+@item glib
+@item gmp
+@item bluez
+@item miniupnpc
+@item gettext
+@item which
+@item texinfo
+@item GNU libmicrohttpd @geq{} 0.9.30 @footnote{We recommend to build it
+with a GnuTLS version that was configured with libunbound ("DANE support")}
+@item GNU libextractor @geq{} 1.0
+@item GNU libtool @geq{} 2.2
+@item GNU libunistring @geq{} 0.9.1.1
+@item GNU libidn @geq{} 1.0.0
+@item @uref{https://gnupg.org/software/libgcrypt/, GNU libgcrypt} @geq{}
+@uref{https://gnupg.org/ftp/gcrypt/libgcrypt/, 1.6.0}
+@item @uref{https://gnutls.org/, GnuTLS} @geq{} 3.2.7
+@footnote{We recommend to compile with libunbound for DANE support;
+GnuTLS also requires GNU nettle 2.7 (update: GnuTLS 3.2.7 appears NOT
+to work against GNU nettle > 2.7, due to some API updatings done by
+nettle. Thus it should be compiled against nettle 2.7
+and, in case you get some error on the reference to `rpl_strerror' being
+undefined, follow the instructions on
+@uref{http://lists.gnupg.org/pipermail/gnutls-devel/2013-November/006588.html, this}
+post (and the link inside it)).}
+@item @uref{https://gnunet.org/gnurl, gnURL} libgnurl @geq{} 7.34.0
+@footnote{must be compiled after @code{GnuTLS}}
+@item libglpk @geq{} 4.45
+@item @uref{http://www.openssl.org/, OpenSSL} @geq{} 1.0
+@item TeX Live @geq{} 2012, optional (for gnunet-bcd)
+@item Texinfo @geq{} 5.2 (for documentation)
+@item libsqlite @geq{} 3.8.0 @footnote{(note that the code will
+compile and often work with lower version numbers, but you may get subtle
+bugs with respect to quota management in certain rare cases);
+alternatively, MySQL or Postgres can also be installed, but those
+databases will require more complex configurations (not
+recommended for first-time users)}
+@item zlib
+@end itemize
+
+@node Fixing libgnurl build issues
+@subsection Fixing libgnurl build issues
+
+If you have to compile libgnurl from source since the version included in
+your distribution is to old you perhaps get an error message while
+running the @file{configure} script:
+
+@example
+$ configure
+...
+checking for 64-bit curl_off_t data type... unknown
+checking for 32-bit curl_off_t data type... unknown
+checking for 16-bit curl_off_t data type... unknown
+configure: error: cannot find data type for curl_off_t.
+@end example
+
+@noindent
+Solution:
+
+Before running the configure script, set:
+
+@example
+CFLAGS="-I. -I$BUILD_ROOT/include"
+@end example
+
+@node Optional dependencies
+@subsection Optional dependencies
+
+These applications must be installed for various experimental or otherwise
+optional features such as @code{gnunet-conversation}, @code{gnunet-gtk}.
+
+@itemize @bullet
+@item libpulse 2.0 or higher, optional (for gnunet-conversation)
+@item libopus 1.0.1 or higher, optional (for gnunet-conversation)
+@item libogg 1.3.0 or higher, optional (for gnunet-conversation)
+@item certool (binary) optional @footnote{for convenient installation of
+the GNS proxy (available as part of Debian's libnss3-tools)}
+@item python-zbar 0.10 or higher, optional (for gnunet-qr)
+@item Gtk+ 3.0 or higher, optional (for gnunet-gtk)
+@item libgladeui must match Gtk+ version, optional (for gnunet-gtk)
+@item libqrencode 3.0 or higher, optional (for gnunet-namestore-gtk)
+@end itemize
+
+@node Internal dependencies
+@subsection Internal dependencies
+
+This section tries to give an overview of what processes a typical GNUnet peer
+running a particular application would consist of. All of the processes listed
+here should be automatically started by @code{gnunet-arm -s}. The list is given
+as a rough first guide to users for failure diagnostics. Ideally, end-users
+should never have to worry about these internal dependencies.
+
+In terms of internal dependencies, a minimum file-sharing system consists of
+the following GNUnet processes (in order of dependency):
+
+@itemize @bullet
+@item gnunet-service-arm
+@item gnunet-service-resolver (required by all)
+@item gnunet-service-statistics (required by all)
+@item gnunet-service-peerinfo
+@item gnunet-service-transport (requires peerinfo)
+@item gnunet-service-core (requires transport)
+@item gnunet-daemon-hostlist (requires core)
+@item gnunet-daemon-topology (requires hostlist, peerinfo)
+@item gnunet-service-datastore
+@item gnunet-service-dht (requires core)
+@item gnunet-service-identity
+@item gnunet-service-fs (requires identity, mesh, dht, datastore, core)
+@end itemize
+
+
+A minimum VPN system consists of the following GNUnet processes (in order of
+dependency):
+
+@itemize @bullet
+@item gnunet-service-arm
+@item gnunet-service-resolver (required by all)
+@item gnunet-service-statistics (required by all)
+@item gnunet-service-peerinfo
+@item gnunet-service-transport (requires peerinfo)
+@item gnunet-service-core (requires transport)
+@item gnunet-daemon-hostlist (requires core)
+@item gnunet-service-dht (requires core)
+@item gnunet-service-mesh (requires dht, core)
+@item gnunet-service-dns (requires dht)
+@item gnunet-service-regex (requires dht)
+@item gnunet-service-vpn (requires regex, dns, mesh, dht)
+@end itemize
+
+
+A minimum GNS system consists of the following GNUnet processes (in order of
+dependency):
+@itemize @bullet
+@item gnunet-service-arm
+@item gnunet-service-resolver (required by all)
+@item gnunet-service-statistics (required by all)
+@item gnunet-service-peerinfo
+@item gnunet-service-transport (requires peerinfo)
+@item gnunet-service-core (requires transport)
+@item gnunet-daemon-hostlist (requires core)
+@item gnunet-service-dht (requires core)
+@item gnunet-service-mesh (requires dht, core)
+@item gnunet-service-dns (requires dht)
+@item gnunet-service-regex (requires dht)
+@item gnunet-service-vpn (requires regex, dns, mesh, dht)
+@item gnunet-service-identity
+@item gnunet-service-namestore (requires identity)
+@item gnunet-service-gns (requires vpn, dns, dht, namestore, identity)
+@end itemize
+
+@node Pre-installation notes
+@section Pre-installation notes
+
+Please note that in the code instructions for the installation,
+@emph{#} indicates commands run as privileged root user and
+@emph{$} shows commands run as unprivileged ("normal") system user.
+
+
+@node Generic installation instructions
+@section Generic installation instructions
+
+First, in addition to the GNUnet sources you must download the latest version
+of various dependencies. Most distributions do not include sufficiently recent
+versions of these dependencies. Thus, a typically installation on a "modern"
+GNU/Linux distribution requires you to install the following
+dependencies (ideally in this order):
+
+@itemize @bullet
+@item libgpgerror and libgcrypt
+@item libnettle and libunbound (possibly from distribution), GnuTLS
+@item libgnurl (read the README)
+@item GNU libmicrohttpd
+@item GNU libextractor
+@end itemize
+
+Make sure to first install the various mandatory and optional
+dependencies including development headers from your distribution.
+
+Other dependencies that you should strongly consider to install is a
+database (MySQL, sqlite or Postgres). The following instructions will assume
+that you installed at least sqlite. For most distributions you should be able
+to find pre-build packages for the database. Again, make sure to install the
+client libraries and the respective development headers (if they are
+packaged separately) as well.
+
+You can find specific, detailed instructions for installing of the dependencies
+(and possibly the rest of the GNUnet installation) in the platform-specific
+descriptions, which are linked from the bottom of this page. Please consult
+them now. If your distribution is not listed, please study the instructions for
+Debian stable carefully as you try to install the dependencies for your own
+distribution. Contributing additional instructions for further platforms is
+always appreciated.
+
+Before proceeding further, please double-check the dependency list.
+Note that in addition to satisfying the dependencies, you might have to
+make sure that development headers for the various libraries are also
+installed.
+There maybe files for other distributions, or you might be able to find
+equivalent packages for your distribution.
+
+While it is possible to build and install GNUnet without having root access,
+we will assume that you have full control over your system in these
+instructions. First, you should create a system user @emph{gnunet} and
+an additional group @emph{gnunetdns}. On Debian and Ubuntu GNU/Linux, type:
+
+@example
+# adduser --system --home /var/lib/gnunet --group \
+--disabled-password gnunet
+# addgroup --system gnunetdns
+@end example
+
+On other Unixes, this should have the same effect:
+
+@example
+# useradd --system --groups gnunet --home-dir /var/lib/gnunet
+# addgroup --system gnunetdns
+@end example
+
+Now compile and install GNUnet using:
+
+@example
+$ tar xvf gnunet-0.10.?.tar.gz
+$ cd gnunet-0.10.?
+$ ./configure --with-sudo=sudo --with-nssdir=/lib
+$ make
+$ sudo make install
+@end example
+
+If you want to be able to enable DEBUG-level log messages, add
+@code{--enable-logging=verbose} to the end of the @code{./configure} command.
+DEBUG-level log messages are in English-only and should only be useful for
+developers (or for filing really detailed bug reports).
+
+Finally, you probably want to compile @code{gnunet-gtk}, which
+includes gnunet-setup (graphical tool for configuration)
+and @code{gnunet-fs-gtk} (graphical tool for file-sharing):
+
+@example
+$ tar xvf gnunet-gtk-0.10.?.tar.gz
+$ cd gnunet-gtk-0.10.?
+$ ./configure --with-gnunet=/usr/local/
+$ make
+$ sudo make install
+$ cd ..
+$ sudo ldconfig # just to be safe
+@end example
+
+Next, edit the file @file{/etc/gnunet.conf} to contain the following:
+
+@example
+[arm]
+SYSTEM_ONLY = YES
+USER_ONLY = NO
+@end example
+
+You may need to update your ld.so cache to include files installed in
+@file{/usr/local/lib}: @code{ # ldconfig }.
+
+Then, switch from user root to user gnunet to start the peer:
+
+@example
+# su -s /bin/sh - gnunet
+$ gnunet-arm -c /etc/gnunet.conf -s
+@end example
+
+You may also want to add the last line in the gnunet users @file{crontab}
+prefixed with @code{@@reboot} so that it is executed whenever the system is
+booted:
+
+@example
+@@reboot /usr/local/bin/gnunet-arm -c /etc/gnunet.conf -s@
+@end example
+
+This will only start the system-wide GNUnet services. Type exit to get back
+your root shell. Now, you need to configure the per-user part. For each
+$USER on the system, run: @code{ # adduser $USER gnunet }.
+
+to allow them to access the system-wide GNUnet services. Then, each
+user should create a configuration file @file{~/.config/gnunet.conf}
+with the lines:
+
+@example
+[arm]
+SYSTEM_ONLY = NO
+USER_ONLY = YES
+DEFAULTSERVICES = gns
+@end example
+
+and start the per-user services using
+
+@code{@
+ $ gnunet-arm -c ~/.config/gnunet.conf -s@
+}@
+
+Again, adding a @code{crontab} entry to autostart the peer is advised:@
+@code{@
+@@reboot /usr/local/bin/gnunet-arm -c $HOME/.config/gnunet.conf -s@
+}@
+
+Note that some GNUnet services (such as SOCKS5 proxies) may need a system-wide
+TCP port for each user. For those services, systems with more than one user may
+require each user to specify a different port number in their personal
+configuration file.
+
+Finally, the user should perform the basic initial setup for the GNU Name
+System. This is done by running two commands:@
+
+@example
+$ gnunet-gns-import.sh@
+$ gnunet-gns-proxy-setup-ca@
+@end example
+
+The first generates the default zones, wheras the second setups the GNS
+Certificate Authority with the user's browser. Now, to actiave GNS in the
+normal DNS resolution process, you need to edit your @file{/etc/nsswitch.conf}
+where you should find a line like this:
+@example
+hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4
+@end example
+
+
+The exact details may differ a bit, which is fine. Add the text
+@emph{"gns [NOTFOUND=return]"} after @emph{"files"}:
+
+@example
+hosts: files gns [NOTFOUND=return] mdns4_minimal [NOTFOUND=return] dns mdns4
+@end example
+
+
+You might want to make sure that @file{/lib/libnss_gns.so.2} exists on your
+system, it should have been created during the installation.
+
+
+
+@node Build instructions for Ubuntu 12.04 using Git
+@section Build instructions for Ubuntu 12.04 using Git
+
+
+@menu
+* Install the required build tools::
+* Install libgcrypt 1.6 and libgpg-error::
+* Install gnutls with DANE support::
+* Install libgnurl::
+* Install libmicrohttpd from Git::
+* Install libextractor from Git::
+* Install GNUnet dependencies::
+* Build GNUnet::
+* Install the GNUnet-gtk user interface from Git::
+@end menu
+
+@node Install the required build tools
+@subsection Install the required build tools
+
+First, make sure Git is installed on your system:
+
+@example
+$ sudo apt-get install git
+@end example
+
+Install the essential buildtools:
+
+@example
+$ sudo apt-get install automake autopoint autoconf libtool
+@end example
+
+@node Install libgcrypt 1.6 and libgpg-error
+@subsection Install libgcrypt 1.6 and libgpg-error
+
+@example
+$ wget ftp://ftp.gnupg.org/gcrypt/libgpg-error/libgpg-error-1.12.tar.bz2
+$ tar xf libgpg-error-1.12.tar.bz2
+$ cd libgpg-error-1.12
+$ ./configure
+$ sudo make install ; cd ..
+@end example
+
+@node Install gnutls with DANE support
+@subsection Install gnutls with DANE support
+
+@example
+$ wget http://www.lysator.liu.se/~nisse/archive/nettle-2.7.1.tar.gz
+$ tar xf nettle-2.7.1.tar.gz
+$ cd nettle-2.7.1
+$ ./configure
+$ sudo make install ; cd ..
+@end example
+
+@example
+$ wget https://www.nlnetlabs.nl/downloads/ldns/ldns-1.6.16.tar.gz
+$ tar xf ldns-1.6.16.tar.gz
+$ cd ldns-1.6.16
+$ ./configure
+$ sudo make install ; cd ..
+@end example
+
+@example
+$ wget https://unbound.net/downloads/unbound-1.4.21.tar.gz
+$ tar xf unbound-1.4.21.tar.gz
+$ cd unbound-1.4.21
+$ ./configure
+$ sudo make install ; cd ..
+@end example
+
+@example
+$ wget ftp://ftp.gnutls.org/gcrypt/gnutls/v3.1/gnutls-3.1.17.tar.xz
+$ tar xf gnutls-3.1.17.tar.xz
+$ cd gnutls-3.1.17
+$ ./configure
+$ sudo make install ; cd ..
+@end example
+
+@example
+$ wget ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.6.0.tar.bz2
+$ tar xf libgcrypt-1.6.0.tar.bz2
+$ cd libgcrypt-1.6.0
+$ ./configure
+$ sudo make install ; cd ..
+@end example
+
+@node Install libgnurl
+@subsection Install libgnurl
+
+@example
+$ wget https://gnunet.org/sites/default/files/gnurl-7.34.0.tar.bz2
+$ tar xf gnurl-7.34.0.tar.bz2
+$ cd gnurl-7.34.0
+$ ./configure --enable-ipv6 --with-gnutls --without-libssh2 \
+ --without-libmetalink --without-winidn --without-librtmp \
+ --without-nghttp2 --without-nss --without-cyassl \
+ --without-polarssl --without-ssl --without-winssl \
+ --without-darwinssl --disable-sspi --disable-ntlm-wb \
+ --disable-ldap --disable-rtsp --disable-dict --disable-telnet \
+ --disable-tftp --disable-pop3 --disable-imap --disable-smtp \
+ --disable-gopher --disable-file --disable-ftp
+$ sudo make install ; cd ..
+@end example
+
+@node Install libmicrohttpd from Git
+@subsection Install libmicrohttpd from Git
+
+@example
+$ git clone https://gnunet.org/git/libmicrohttpd
+$ cd libmicrohttpd/
+$ ./bootstrap
+$ ./configure
+$ sudo make install ; cd ..
+@end example
+
+@node Install libextractor from Git
+@subsection Install libextractor from Git
+
+Install libextractor dependencies:
+
+@example
+$ sudo apt-get install zlib1g-dev libgsf-1-dev libmpeg2-4-dev \
+ libpoppler-dev libvorbis-dev libexiv2-dev libjpeg-dev \
+ libtiff-dev libgif-dev libvorbis-dev libflac-dev libsmf-dev \
+ g++
+@end example
+
+Build libextractor:
+
+@example
+$ git clone https://gnunet.org/git/libextractor
+$ cd libextractor
+$ ./bootstrap
+$ ./configure
+$ sudo make install ; cd ..
+@end example
+
+@node Install GNUnet dependencies
+@subsection Install GNUnet dependencies
+
+@example
+$ sudo apt-get install libidn11-dev libunistring-dev libglpk-dev \
+ libpulse-dev libbluetooth-dev libsqlite-dev
+@end example
+
+Install libopus:
+
+@example
+$ wget http://downloads.xiph.org/releases/opus/opus-1.1.tar.gz
+$ tar xf opus-1.1.tar.gz
+$ cd opus-1.1/
+$ ./configure
+$ sudo make install ; cd ..
+@end example
+
+Choose one or more database backends:
+
+SQLite3:
+@example
+$ sudo apt-get install libsqlite3-dev
+@end example
+MySQL:
+@example
+$ sudo apt-get install libmysqlclient-dev
+@end example
+PostgreSQL:
+@example
+$ sudo apt-get install libpq-dev postgresql
+@end example
+
+
+
+@node Build GNUnet
+@subsection Build GNUnet
+
+
+
+@menu
+* Configuring the installation path::
+* Configuring the system::
+* Installing components requiring sudo permission::
+* Build::
+@end menu
+
+@node Configuring the installation path
+@subsubsection Configuring the installation path
+
+You can specify the location of the GNUnet installation by setting the prefix
+when calling the configure script with @code{--prefix=DIRECTORY}
+
+@example
+$ export PATH=$PATH:DIRECTORY/bin
+@end example
+
+@node Configuring the system
+@subsubsection Configuring the system
+
+Please make sure NOW that you have created a user and group 'gnunet'
+and additionally a group 'gnunetdns':
+
+@example
+$ sudo addgroup gnunet
+$ sudo addgroup gnunetdns
+$ sudo adduser gnunet
+@end example
+
+Each GNUnet user should be added to the 'gnunet' group (may
+require fresh login to come into effect):
+
+@example
+$ sudo useradd -G gnunet
+@end example
+
+@node Installing components requiring sudo permission
+@subsubsection Installing components requiring sudo permission
+
+Some components, like the nss plugin required for GNS, may require root
+permissions. To allow these few components to be installed use:
+
+@example
+$ ./configure --with-sudo
+@end example
+
+@node Build
+@subsubsection Build
+
+@example
+$ git clone https://gnunet.org/git/gnunet/
+$ cd gnunet/
+$ ./bootstrap
+@end example
+
+Use the required configure call including the optional installation prefix
+PREFIX or the sudo permissions:
+
+@example
+$ ./configure [ --with-sudo | --with-prefix=PREFIX ]
+@end example
+
+@example
+$ make; sudo make install
+@end example
+
+After installing it, you need to create an empty configuration file:
+
+@example
+mkdir ~/.gnunet; touch ~/.gnunet/gnunet.conf
+@end example
+
+And finally you can start GNUnet with @code{$ gnunet-arm -s}.
+
+@node Install the GNUnet-gtk user interface from Git
+@subsection Install the GNUnet-gtk user interface from Git
+
+
+Install depencies:
+
+@example
+$ sudo apt-get install libgtk-3-dev libunique-3.0-dev libgladeui-dev \
+libqrencode-dev
+@end example
+
+To build GNUnet (with an optional prefix)and execute:
+
+@example
+$ git clone https://gnunet.org/git/gnunet-gtk/
+$ cd gnunet-gtk/
+$ ./bootstrap
+$ ./configure [--prefix=PREFIX] --with-gnunet=DIRECTORY
+$ make; sudo make install
+@end example
+
+@node Build Instructions for Microsoft Windows Platforms
+@section Build Instructions for Microsoft Windows Platforms
+
+@menu
+* Introduction to building on MS Windows::
+* Requirements::
+* Dependencies & Initial Setup::
+* GNUnet Installation::
+* Adjusting Windows for running and testing GNUnet::
+* Building the GNUnet Installer::
+* Using GNUnet with Netbeans on Windows::
+@end menu
+
+@node Introduction to building on MS Windows
+@subsection Introduction to building on MS Windows
+
+
+This document is a guide to building GNUnet and its dependencies on Windows
+platforms. GNUnet development is mostly done under Linux and especially SVN
+checkouts may not build out of the box. We regret any inconvenience, and
+if you have problems, please report them.
+
+@node Requirements
+@subsection Requirements
+
+The Howto is based upon a @strong{Windows Server 2008 32bit@strong{
+Installation, @strong{sbuild} and thus a @uref{http://www.mingw.org/wiki/MSYS,
+MSYS+MinGW} (W32-GCC-Compiler-Suite + Unix-like Userland) installation. sbuild
+is a convenient set of scripts which creates a working msys/mingw installation
+and installs most dependencies required for GNUnet. }}
+
+As of the point of the creation of this Howto, GNUnet @strong{requires} a
+Windows @strong{Server} 2003 or newer for full feature support. Windows Vista
+and later will also work, but
+@strong{non-server version can not run a VPN-Exit-Node} as the NAT features
+have been removed as of Windows Vista.
+
+@node Dependencies & Initial Setup
+@subsection Dependencies & Initial Setup
+
+
+@itemize @bullet
+
+@item
+Install a fresh version of @strong{Python 2.x}, even if you are using a x64-OS,
+install a 32-bit version for use with sbuild. Python 3.0 currently is
+incompatible.
+
+@item
+Install your favorite @uref{http://code.google.com/p/tortoisegit/, GIT} &
+@uref{http://tortoisesvn.net/, SVN}-clients.
+
+@item
+You will also need some archive-manager like @uref{http://www.7-zip.org/, 7zip}.
+
+@item
+Pull a copy of sbuild to a directory of your choice, which will be used in the
+remainder of this guide. For now, we will use @file{c:\gnunet\sbuild\}
+
+@item
+in @file{sbuild\src\mingw\mingw32-buildall.sh}, comment out the packages
+@strong{gnunet-svn} and @strong{gnunet-gtk-svn}, as we don't want sbuild to
+compile/install those for us.
+
+@item
+Follow LRN's sbuild installation instructions.-
+@end itemize
+
+Please note that sbuild may (or will most likely) fail during installation,
+thus you really HAVE to @strong{check the logfiles} created during the
+installation process. Certain packages may fail to build initially due to
+missing dependencies, thus you may have to
+@strong{substitute those with binary-versions initially}. Later on once
+dependencies are satisfied you can re-build the newer package versions.
+
+@strong{It is normal that you may have to repeat this step multiple times and
+there is no uniform way to fix all compile-time issues, as the build-process
+of many of the dependencies installed are rather unstable on win32 and certain
+releases may not even compile at all.}
+
+Most dependencies for GNUnet have been set up by sbuild, thus we now should add
+the @file{bin/} directories in your new msys and mingw installations to PATH.
+You will want to create a backup of your finished msys-environment by now.
+
+@node GNUnet Installation
+@subsection GNUnet Installation
+
+First, we need to launch our msys-shell, you can do this via
+
+@file{C:\gnunet\sbuild\msys\msys.bat}
+
+You might wish to take a look at this file and adjust some login-parameters to
+your msys environment.
+
+Also, sbuild added two pointpoints to your msys-environment, though those
+might remain invisible:
+
+@itemize @bullet
+
+@item
+/mingw, which will mount your mingw-directory from sbuild/mingw and the other one is
+
+@item
+/src which contains all the installation sources sbuild just compiled.
+@end itemize
+
+Check out the current gnunet-sources (svn-head) from the gnunet-repository,
+we will do this in your home directory:
+
+@code{svn checkout https://gnunet.org/svn/gnunet/ ~/gnunet}
+
+Now, we will first need to bootstrap the checked out installation and then
+configure it accordingly.
+
+@example
+cd ~/gnunet
+./bootstrap
+STRIP=true CPPFLAGS="-DUSE_IPV6=1 -DW32_VEH" CFLAGS="$CFLAGS -g -O2" \
+./configure --prefix=/ --docdir=/share/doc/gnunet \
+--with-libiconv-prefix=/mingw --with-libintl-prefix=/mingw \
+--with-libcurl=/mingw --with-extractor=/mingw --with-sqlite=/mingw \
+--with-microhttpd=/mingw --with-plibc=/mingw --enable-benchmarks \
+--enable-expensivetests --enable-experimental --with-qrencode=/mingw \
+--enable-silent-rules --enable-experimental 2>&1 | tee -a ./configure.log
+@end example
+
+The parameters above will configure for a reasonable gnunet installation to the
+your msys-root directory. Depending on which features your would like to build
+or you may need to specify additional dependencies. Sbuild installed most libs
+into the /mingw subdirectory, so remember to prefix library locations with
+this path.
+
+Like on a unixoid system, you might want to use your home directory as prefix
+for your own gnunet installation for development, without tainting the
+buildenvironment. Just change the "prefix" parameter to point towards
+~/ in this case.
+
+Now it's time to compile gnunet as usual. Though this will take some time, so
+you may fetch yourself a coffee or some Mate now...
+
+@example
+make ; make install
+@end example
+
+@node Adjusting Windows for running and testing GNUnet
+@subsection Adjusting Windows for running and testing GNUnet
+
+Assuming the build succeeded and you
+@strong{added the bin directory of your gnunet to PATH}, you can now use your
+gnunet-installation as usual. Remember that UAC or the windows firewall may
+popup initially, blocking further execution of gnunet until you acknowledge
+them (duh!).
+
+You will also have to take the usual steps to get p2p software running properly
+(port forwarding, ...), and gnunet will require administrative permissions as
+it may even install a device-driver (in case you are using gnunet-vpn and/or
+gnunet-exit).
+
+@node Building the GNUnet Installer
+@subsection Building the GNUnet Installer
+
+The GNUnet installer is made with @uref{http://nsis.sourceforge.net/, NSIS}
+The installer script is located in @file{contrib\win} in the
+GNUnet source tree.
+
+@node Using GNUnet with Netbeans on Windows
+@subsection Using GNUnet with Netbeans on Windows
+
+TODO
+
+@node Build instructions for Debian 7.5
+@section Build instructions for Debian 7.5
+
+
+These are the installation instructions for Debian 7.5. They were tested using
+a minimal, fresh Debian 7.5 AMD64 installation without non-free software
+(no contrib or non-free). By "minimal", we mean that during installation, we
+did not select any desktop environment, servers or system utilities during the
+"tasksel" step. Note that the packages and the dependencies that we will
+install during this chapter take about 1.5 GB of disk space. Combined with
+GNUnet and space for objects during compilation, you should not even attempt
+this unless you have about 2.5 GB free after the minimal Debian installation.
+Using these instructions to build a VM image is likely to require a minimum of
+4-5 GB for the VM (as you will likely also want a desktop manager).
+
+GNUnet's security model assumes that your @file{/home} directory is encrypted.
+Thus, if possible, you should encrypt your home partition
+(or per-user home directory).
+
+Naturally, the exact details of the starting state for your installation
+should not matter much. For example, if you selected any of those installation
+groups you might simply already have some of the necessary packages installed.
+We did this for testing, as this way we are less likely to forget to mention a
+required package. Note that we will not install a desktop environment, but of
+course you will need to install one to use GNUnet's graphical user interfaces.
+Thus, it is suggested that you simply install the desktop environment of your
+choice before beginning with the instructions.
+
+
+
+@menu
+* Update::
+* Stable? Hah!::
+* Update again::
+* Installing packages::
+* Installing dependencies from source::
+* Installing GNUnet from source::
+* But wait there is more!::
+@end menu
+
+@node Update
+@subsection Update
+
+After any installation, you should begin by running
+
+@example
+# apt-get update ; apt-get upgrade
+@end example
+
+to ensure that all of your packages are up-to-date. Note that the "#" is used
+to indicate that you need to type in this command as "root"
+(or prefix with "sudo"), whereas "$" is used to indicate typing in a command
+as a normal user.
+
+@node Stable? Hah!
+@subsection Stable? Hah!
+
+Yes, we said we start with a Debian 7.5 "stable" system. However, to reduce the
+amount of compilation by hand, we will begin by allowing the installation of
+packages from the testing and unstable distributions as well. We will stick to
+"stable" packages where possible, but some packages will be taken from the
+other distributions. Start by modifying @file{/etc/apt/sources.list} to contain
+the following (possibly adjusted to point to your mirror of choice):
+@example
+# These were there before:
+deb http://ftp.de.debian.org/debian/ wheezy main
+deb-src http://ftp.de.debian.org/debian/ wheezy main
+deb http://security.debian.org/ wheezy/updates main
+deb-src http://security.debian.org/ wheezy/updates main
+deb http://ftp.de.debian.org/debian/ wheezy-updates main
+deb-src http://ftp.de.debian.org/debian/ wheezy-updates main
+
+# Add these lines (feel free to adjust the mirror):
+deb http://ftp.de.debian.org/debian/ testing main
+deb http://ftp.de.debian.org/debian/ unstable main
+@end example
+
+The next step is to create/edit your @file{/etc/apt/preferences} file to look
+like this:
+
+@example
+Package: *
+Pin: release a=stable,n=wheezy
+Pin-Priority: 700
+
+Package: *
+Pin: release o=Debian,a=testing
+Pin-Priority: 650
+
+Package: *
+Pin: release o=Debian,a=unstable
+Pin-Priority: 600
+@end example
+
+You can read more about Apt Preferences here and here. Note that other pinnings
+are likely to also work for GNUnet, the key thing is that you need some
+packages from unstable (as shown below). However, as unstable is unlikely to
+be comprehensive (missing packages) or might be problematic (crashing packages),
+you probably want others from stable and/or testing.
+
+@node Update again
+@subsection Update again
+
+Now, run again@
+
+@example
+# apt-get update@
+# apt-get upgrade@
+@end example
+
+to ensure that all your new distribution indices are downloaded, and that your
+pinning is correct: the upgrade step should cause no changes at all.
+
+@node Installing packages
+@subsection Installing packages
+
+We begin by installing a few Debian packages from stable:@
+
+@example
+# apt-get install gcc make python-zbar libltdl-dev libsqlite3-dev \
+ libunistring-dev libopus-dev libpulse-dev openssl libglpk-dev \
+ texlive libidn11-dev libmysqlclient-dev libpq-dev libarchive-dev \
+ libbz2-dev libexiv2-dev libflac-dev libgif-dev libglib2.0-dev \
+ libgtk-3-dev libmagic-dev libjpeg8-dev libmpeg2-4-dev libmp4v2-dev \
+ librpm-dev libsmf-dev libtidy-dev libtiff5-dev libvorbis-dev \
+ libogg-dev zlib1g-dev g++ gettext libgsf-1-dev libunbound-dev \
+ libqrencode-dev libgladeui-dev nasm texlive-latex-extra \
+ libunique-3.0-dev gawk miniupnpc libfuse-dev libbluetooth-dev
+@end example
+
+After that, we install a few more packages from unstable:@
+
+@example
+# apt-get install -t unstable nettle-dev libgstreamer1.0-dev \
+ gstreamer1.0-plugins-base gstreamer1.0-plugins-good \
+ libgstreamer-plugins-base1.0-dev
+@end example
+
+@node Installing dependencies from source
+@subsection Installing dependencies from source
+
+Next, we need to install a few dependencies from source. You might want to do
+this as a "normal" user and only run the @code{make install} steps as root
+(hence the @code{sudo} in the commands below). Also, you do this from any
+directory. We begin by downloading all dependencies, then extracting the
+sources, and finally compiling and installing the libraries:@
+
+@example
+$ wget https://libav.org/releases/libav-9.10.tar.xz
+$ wget http://ftp.gnu.org/gnu/libextractor/libextractor-1.3.tar.gz
+$ wget ftp://ftp.gnupg.org/gcrypt/libgpg-error/libgpg-error-1.12.tar.bz2
+$ wget ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.6.0.tar.bz2
+$ wget ftp://ftp.gnutls.org/gcrypt/gnutls/v3.2/gnutls-3.2.7.tar.xz
+$ wget http://ftp.gnu.org/gnu/libmicrohttpd/libmicrohttpd-0.9.33.tar.gz
+$ wget https://gnunet.org/sites/default/files/gnurl-7.34.0.tar.bz2
+$ tar xvf libextractor-1.3.tar.gz
+$ tar xvf libgpg-error-1.12.tar.bz2
+$ tar xvf libgcrypt-1.6.0.tar.bz2
+$ tar xvf gnutls-3.2.7.tar.xz
+$ tar xvf libmicrohttpd-0.9.33.tar.gz
+$ tar xvf gnurl-7.34.0.tar.bz2
+$ cd libav-0.9 ; ./configure --enable-shared;
+$ make; sudo make install; cd ..
+$ cd libextractor-1.3 ; ./configure;
+$ make ; sudo make install; cd ..
+$ cd libgpg-error-1.12; ./configure;
+$ make ; sudo make install; cd ..
+$ cd libgcrypt-1.6.0; ./configure --with-gpg-error-prefix=/usr/local;
+$ make ; sudo make install ; cd ..
+$ cd gnutls-3.2.7 ; ./configure;
+$ make ; sudo make install ; cd ..
+$ cd libmicrohttpd-0.9.33; ./configure;
+$ make ; sudo make install ; cd ..
+$ cd gnurl-7.34.0
+$ ./configure --enable-ipv6 --with-gnutls=/usr/local --without-libssh2 \
+ --without-libmetalink --without-winidn --without-librtmp --without-nghttp2 \
+ --without-nss --without-cyassl --without-polarssl --without-ssl \
+ --without-winssl --without-darwinssl --disable-sspi --disable-ntlm-wb \
+ --disable-ldap --disable-rtsp --disable-dict --disable-telnet --disable-tftp \
+ --disable-pop3 --disable-imap --disable-smtp --disable-gopher --disable-file \
+ --disable-ftp
+$ make ; sudo make install; cd ..
+@end example
+
+@node Installing GNUnet from source
+@subsection Installing GNUnet from source
+
+
+For this, simply follow the generic installation instructions from
+here.
+
+@node But wait there is more!
+@subsection But wait there is more!
+
+So far, we installed all of the packages and dependencies required to ensure
+that all of GNUnet would be built. However, while for example the plugins to
+interact with the MySQL or Postgres databases have been created, we did not
+actually install or configure those databases. Thus, you will need to install
+and configure those databases or stick with the default Sqlite database.
+Sqlite is usually fine for most applications, but MySQL can offer better
+performance and Postgres better resillience.
+
+
+@node Installing GNUnet from Git on Ubuntu 14.4
+@section Installing GNUnet from Git on Ubuntu 14.4
+
+@strong{Install the required build tools:}
+@code{ $ sudo apt-get install git automake autopoint autoconf }
+
+@strong{Install the required dependencies}
+@example
+$ sudo apt-get install libltdl-dev libgpg-error-dev libidn11-dev \
+ libunistring-dev libglpk-dev libbluetooth-dev libextractor-dev \
+ libmicrohttpd-dev libgnutls28-dev
+@end example
+
+@strong{Choose one or more database backends}
+
+SQLite3:
+@example
+$ sudo apt-get install libsqlite3-dev
+@end example
+MySQL:
+@example
+$ sudo apt-get install libmysqlclient-dev
+@end example
+PostgreSQL:
+@example
+$ sudo apt-get install libpq-dev postgresql
+@end example
+
+@strong{Install the optional dependencies for gnunet-conversation:}
+
+@example
+$ sudo apt-get install gstreamer1.0 libpulse-dev libopus-dev
+@end example
+
+@strong{Install the libgrypt 1.6.1:}
+For Ubuntu 14.04:
+@example
+$ sudo apt-get install libgcrypt20-dev
+@end example
+For Ubuntu older 14.04:
+@example
+$ wget ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.6.1.tar.bz2
+$ tar xf libgcrypt-1.6.1.tar.bz2
+$ cd libgcrypt-1.6.1
+$ ./configure
+$ sudo make install
+$ cd ..
+@end example
+@strong{Install libgnurl}
+@example
+$ wget https://gnunet.org/sites/default/files/gnurl-7.35.0.tar.bz2
+$ tar xf gnurl-7.35.0.tar.bz2
+$ cd gnurl-7.35.0
+$ ./configure --enable-ipv6 --with-gnutls --without-libssh2 \
+ --without-libmetalink --without-winidn --without-librtmp --without-nghttp2 \
+ --without-nss --without-cyassl --without-polarssl --without-ssl \
+ --without-winssl --without-darwinssl --disable-sspi --disable-ntlm-wb \
+ --disable-ldap --disable-rtsp --disable-dict --disable-telnet --disable-tftp \
+ --disable-pop3 --disable-imap --disable-smtp --disable-gopher --disable-file \
+ --disable-ftp
+$ sudo make install
+$ cd ..
+@end example
+
+@strong{Install GNUnet}
+@example
+$ git clone https://gnunet.org/git/gnunet/
+$ cd gnunet/
+$ ./bootstrap
+@end example
+
+If you want to:
+@itemize @bullet
+
+
+@item
+Install to a different directory:@
+ --prefix=PREFIX
+
+@item
+Have sudo permission, but do not want to compile as root:@
+ --with-sudo
+
+@item
+Want debug message enabled:@
+ -- enable-logging=verbose
+@end itemize
+
+
+@code{@
+ $ ./configure [ --with-sudo | --prefix=PREFIX | --- enable-logging=verbose]@
+ $ make; sudo make install@
+}
+
+After installing it, you need to create an empty configuration file:@
+@code{touch ~/.config/gnunet.conf}
+
+And finally you can start GNUnet with@
+@code{$ gnunet-arm -s}
+
+@node Build instructions for Debian 8
+@section Build instructions for Debian 8
+
+These are the installation instructions for Debian 8. They were tested using a
+fresh Debian 8 AMD64 installation without non-free software (no contrib or
+non-free). During installation, I only selected "lxde" for the desktop
+environment. Note that the packages and the dependencies that we will install
+during this chapter take about 1.5 GB of disk space. Combined with GNUnet and
+space for objects during compilation, you should not even attempt this unless
+you have about 2.5 GB free after the Debian installation. Using these
+instructions to build a VM image is likely to require a minimum of 4-5 GB for
+the VM (as you will likely also want a desktop manager).
+
+GNUnet's security model assumes that your @code{/home} directory is encrypted.
+Thus, if possible, you should encrypt your entire disk, or at least just your
+home partition (or per-user home directory).
+
+Naturally, the exact details of the starting state for your installation should
+not matter much. For example, if you selected any of those installation groups
+you might simply already have some of the necessary packages installed. Thus,
+it is suggested that you simply install the desktop environment of your choice
+before beginning with the instructions.
+
+
+@menu
+* Update Debian::
+* Installing Debian Packages::
+* Installing Dependencies from Source2::
+* Installing GNUnet from Source2::
+* But wait (again) there is more!::
+@end menu
+
+@node Update Debian
+@subsection Update Debian
+
+After any installation, you should begin by running@
+@code{@
+ # apt-get update@
+ # apt-get upgrade@
+}@
+to ensure that all of your packages are up-to-date. Note that the "#" is used
+to indicate that you need to type in this command as "root" (or prefix with
+"sudo"), whereas "$" is used to indicate typing in a command as a normal
+user.
+
+@node Installing Debian Packages
+@subsection Installing Debian Packages
+
+We begin by installing a few Debian packages from stable:@
+@example
+ # apt-get install gcc make python-zbar libltdl-dev libsqlite3-dev \
+ libunistring-dev libopus-dev libpulse-dev openssl libglpk-dev texlive \
+ libidn11-dev libmysqlclient-dev libpq-dev libarchive-dev libbz2-dev \
+ libflac-dev libgif-dev libglib2.0-dev libgtk-3-dev libmpeg2-4-dev \
+ libtidy-dev libvorbis-dev libogg-dev zlib1g-dev g++ gettext libgsf-1-dev \
+ libunbound-dev libqrencode-dev libgladeui-dev nasm texlive-latex-extra \
+ libunique-3.0-dev gawk miniupnpc libfuse-dev libbluetooth-dev \
+ gstreamer1.0-plugins-base gstreamer1.0-plugins-good \
+ libgstreamer-plugins-base1.0-dev nettle-dev libextractor-dev libgcrypt20-dev \
+ libmicrohttpd-dev
+@end example
+
+@node Installing Dependencies from Source2
+@subsection Installing Dependencies from Source2
+
+Yes, we said we start with a Debian 8 "stable" system, but because Debian
+linked GnuTLS without support for DANE, we need to compile a few things, in
+addition to GNUnet, still by hand. Yes, you can run GNUnet using the respective
+Debian packages, but then you will not get DANE support.
+
+Next, we need to install a few dependencies from source. You might want to do
+this as a "normal" user and only run the @code{make install} steps as root
+(hence the @code{sudo} in the commands below). Also, you do this from any
+directory. We begin by downloading all dependencies, then extracting the
+sources, and finally compiling and installing the libraries:@
+
+@code{@
+ $ wget ftp://ftp.gnutls.org/gcrypt/gnutls/v3.3/gnutls-3.3.12.tar.xz@
+ $ wget https://gnunet.org/sites/default/files/gnurl-7.40.0.tar.bz2@
+ $ tar xvf gnutls-3.3.12.tar.xz@
+ $ tar xvf gnurl-7.40.0.tar.bz2@
+ $ cd gnutls-3.3.12 ; ./configure ; make ; sudo make install ; cd ..@
+ $ cd gnurl-7.40.0@
+ $ ./configure --enable-ipv6 --with-gnutls=/usr/local --without-libssh2 \
+ --without-libmetalink --without-winidn --without-librtmp --without-nghttp2 \
+ --without-nss --without-cyassl --without-polarssl --without-ssl \
+ --without-winssl --without-darwinssl --disable-sspi --disable-ntlm-wb \
+ --disable-ldap --disable-rtsp --disable-dict --disable-telnet --disable-tftp \
+ --disable-pop3 --disable-imap --disable-smtp --disable-gopher --disable-file \
+ --disable-ftp --disable-smb
+ $ make ; sudo make install; cd ..@
+}
+
+@node Installing GNUnet from Source2
+@subsection Installing GNUnet from Source2
+
+For this, simply follow the generic installation instructions from@
+here.
+
+@node But wait (again) there is more!
+@subsection But wait (again) there is more!
+
+So far, we installed all of the packages and dependencies required to ensure
+that all of GNUnet would be built. However, while for example the plugins to
+interact with the MySQL or Postgres databases have been created, we did not
+actually install or configure those databases. Thus, you will need to install
+and configure those databases or stick with the default Sqlite database. Sqlite
+is usually fine for most applications, but MySQL can offer better performance
+and Postgres better resillience.
+
+@node Outdated build instructions for previous revisions
+@section Outdated build instructions for previous revisions
+
+This chapter contains a collection of outdated, older installation guides. They
+are mostly intended to serve as a starting point for writing up-to-date
+instructions and should not be expected to work for GNUnet 0.10.x.
+A set of older installation instructions can also be found in the
+@file{doc/outdated-and-old-installation-instructions.txt} in the source
+of GNUnet. This file covers old instructions which no longer receive
+security updates or any kind of support.
+
+
+@menu
+* Installing GNUnet 0.10.1 on Ubuntu 14.04::
+* Building GLPK for MinGW::
+* GUI build instructions for Ubuntu 12.04 using Subversion::
+* Installation with gnunet-update::
+* Instructions for Microsoft Windows Platforms (Old)::
+@end menu
+
+
+@node Installing GNUnet 0.10.1 on Ubuntu 14.04
+@subsection Installing GNUnet 0.10.1 on Ubuntu 14.04
+
+Install the required dependencies@
+
+@example
+$ sudo apt-get install libltdl-dev libgpg-error-dev libidn11-dev \
+ libunistring-dev libglpk-dev libbluetooth-dev libextractor-dev \
+ libmicrohttpd-dev libgnutls28-dev
+@end example
+
+Choose one or more database backends@
+SQLite3@
+@code{@
+ $ sudo apt-get install libsqlite3-dev@
+}@
+MySQL@
+@code{@
+ $ sudo apt-get install libmysqlclient-dev@
+}@
+PostgreSQL@
+@code{@
+ $ sudo apt-get install libpq-dev postgresql@
+}
+
+Install the optional dependencies for gnunet-conversation:@
+@code{@
+ $ sudo apt-get install gstreamer1.0 libpulse-dev libopus-dev@
+}
+
+Install the libgrypt 1.6:@
+For Ubuntu 14.04:@
+@code{$ sudo apt-get install libgcrypt20-dev}@
+For Ubuntu older 14.04:@
+@code{$ wget ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.6.1.tar.bz2@
+ $ tar xf libgcrypt-1.6.1.tar.bz2@
+ $ cd libgcrypt-1.6.1@
+ $ ./configure@
+ $ sudo make install@
+ $ cd ..}
+
+Install libgnurl@
+@example
+ $ wget https://gnunet.org/sites/default/files/gnurl-7.35.0.tar.bz2@
+ $ tar xf gnurl-7.35.0.tar.bz2@
+ $ cd gnurl-7.35.0@
+ $ ./configure --enable-ipv6 --with-gnutls --without-libssh2 \
+ --without-libmetalink --without-winidn --without-librtmp --without-nghttp2 \
+ --without-nss --without-cyassl --without-polarssl --without-ssl \
+ --without-winssl --without-darwinssl --disable-sspi --disable-ntlm-wb \
+ --disable-ldap --disable-rtsp --disable-dict --disable-telnet --disable-tftp \
+ --disable-pop3 --disable-imap --disable-smtp --disable-gopher --disable-file \
+ --disable-ftp@
+ $ sudo make install@
+ $ cd ..@
+@end example
+
+Install GNUnet@
+@code{@
+ $ wget http://ftpmirror.gnu.org/gnunet/gnunet-0.10.1.tar.gz@
+ $ tar xf gnunet-0.10.1.tar.gz@
+ $ cd gnunet-0.10.1@
+}
+
+If you want to:
+@itemize @bullet
+
+@item
+Install to a different directory:@
+ --prefix=PREFIX
+
+@item
+Have sudo permission, but do not want to compile as root:@
+ --with-sudo
+
+@item
+Want debug message enabled:@
+ -- enable-logging=verbose
+@end itemize
+
+@code{@
+ $ ./configure [ --with-sudo | --prefix=PREFIX | --enable-logging=verbose]@
+ $ make; sudo make install@
+}
+
+After installing it, you need to create an empty configuration file:@
+@code{touch ~/.config/gnunet.conf}
+
+And finally you can start GNUnet with@
+@code{$ gnunet-arm -s}
+
+@node Building GLPK for MinGW
+@subsection Building GLPK for MinGW
+
+GNUnet now requires the GNU Linear Programming Kit (GLPK). Since there's is no
+package you can install with @code{mingw-get} you have to compile it from
+source:
+
+@itemize @bullet
+
+@item
+Download the latest version from http://ftp.gnu.org/gnu/glpk/
+
+@item
+Unzip it using your favourite unzipper@
+In the MSYS shell:
+
+@item
+change to the respective directory
+
+@item
+@code{./configure '--build=i686-pc-mingw32'}
+
+@item
+run @code{make install check }
+
+MinGW does not automatically detect the correct buildtype so you have to
+specify it manually
+@end itemize
+
+
+@node GUI build instructions for Ubuntu 12.04 using Subversion
+@subsection GUI build instructions for Ubuntu 12.04 using Subversion
+
+After installing GNUnet you can continue installing the GNUnet GUI tools:
+
+First, install the required dependencies:
+
+@code{@
+ $ sudo apt-get install libgladeui-dev libqrencode-dev@
+}
+
+Please ensure that the GNUnet shared libraries can be found by the linker. If
+you installed GNUnet libraries in a non standard path (say
+GNUNET_PREFIX=/usr/local/lib/), you can
+@itemize @bullet
+
+
+@item
+set the environmental variable permanently to@
+@code{LD_LIBRARY_PATH=$GNUNET_PREFIX}
+
+@item
+or add @code{$GNUNET_PREFIX} to @code{/etc/ld.so.conf}
+@end itemize
+
+
+Now you can checkout and compile the GNUnet GUI tools@
+@code{@
+ $ svn co https://gnunet.org/svn/gnunet-gtk@
+ $ cd gnunet-gtk@
+ $ ./bootstrap@
+ $ ./configure --prefix=$GNUNET_PREFIX/.. --with-gnunet=$GNUNET_PREFIX/..@
+ $ make install@
+}
+
+@node Installation with gnunet-update
+@subsection Installation with gnunet-update
+
+gnunet-update project is an effort to introduce updates to GNUnet
+installations. An interesting to-be-implemented-feature of gnunet-update is
+that these updates are propagated through GNUnet's peer-to-peer network. More
+information about gnunet-update can be found at
+https://gnunet.org/svn/gnunet-update/README.
+
+While the project is still under development, we have implemented the following
+features which we believe may be helpful for users and we would like them to be
+tested:
+
+@itemize @bullet
+
+@item
+Packaging GNUnet installation along with its run-time dependencies into update
+packages
+
+@item
+Installing update packages into compatible hosts
+
+@item
+Updating an existing installation (which had been installed by gnunet-update)
+to a newer one
+@end itemize
+
+The above said features of gnunet-update are currently available for testing on
+GNU/Linux systems.
+
+The following is a guide to help you get started with gnunet-update. It shows
+you how to install the testing binary packages of GNUnet 0.9.1 we have at
+https://gnunet.org/install/
+
+gnunet-update needs the following:
+
+@itemize @bullet
+@item
+python ( 2.6 or above)
+
+@item
+gnupg
+
+@item
+python-gpgme
+@end itemize
+
+
+Checkout gnunet-update:@
+@code{@
+ $ svn checkout -r24905 https://gnunet.org/svn/gnunet-update@
+}
+
+For security reasons, all packages released for gnunet-update from us are
+signed with the key at https://gnunet.org/install/key.txt You would need to
+import this key into your gpg key ring. gnunet-update uses this key to verify
+the integrity of the packages it installs@
+@code{@
+ $ gpg --recv-keys 7C613D78@
+}
+
+Download the packages relevant to your architecture (currently I have access to
+GNU/Linux machines on x86_64 and i686, so only two for now, hopefully more
+later) from https://gnunet.org/install/.
+
+To install the downloaded package into the directory /foo:
+
+@code{@
+ gnunet-update/bin/gnunet-update install downloaded/package /foo@
+}
+
+The installer reports the directories into which shared libraries and
+dependencies have been installed. You may need to add the reported shared
+library installation paths to LD_LIBRARY_PATH before you start running any
+installed binaries.
+
+Please report bugs at https://gnunet.org/bugs/ under the project
+'gnunet-update'.
+
+@node Instructions for Microsoft Windows Platforms (Old)
+@subsection Instructions for Microsoft Windows Platforms (Old)
+
+This document is a DEPRECATED installation guide for gnunet on windows. It will
+not work for recent gnunet versions, but maybe it will be of some use if
+problems arise.
+
+ The Windows build uses a UNIX emulator for Windows,
+ @uref{http://www.mingw.org/, MinGW}, to build the executable modules. These
+ modules run natively on Windows and do not require additional emulation
+ software besides the usual dependencies.
+
+ GNUnet development is mostly done under Linux and especially SVN checkouts may
+ not build out of the box. We regret any inconvenience, and if you have
+ problems, please report them.
+
+
+
+@menu
+* Hardware and OS requirements::
+* Software installation::
+* Building libextractor and GNUnet::
+* Installer::
+* Source::
+@end menu
+
+@node Hardware and OS requirements
+@subsubsection Hardware and OS requirements
+
+@itemize @bullet
+
+@item
+Pentium II or equivalent processor, 350 MHz or better
+
+@item
+128 MB RAM
+
+@item
+600 MB free disk space
+
+@item
+Windows 2000 or Windows XP are recommended
+@end itemize
+
+@node Software installation
+@subsubsection Software installation
+
+@itemize @bullet
+
+@item
+@strong{Compression software}@
+@
+ The software packages GNUnet depends on are usually compressed using UNIX
+ tools like tar, gzip and bzip2.@ If you do not already have an utility that is
+ able to extract such archives, get @uref{http://www.7-zip.org/, 7-Zip}.
+
+@item
+@strong{UNIX environment}@
+@
+The MinGW project provides the compiler toolchain that is used to build
+GNUnet.@ Get the following packages from
+@uref{http://sourceforge.net/projects/mingw/files/, the MinGW project}:
+@itemize @bullet
+
+
+@item
+GCC core
+
+@item
+GCC g++
+
+@item
+MSYS
+
+@item
+MSYS Developer Tool Kit (msysDTK)
+
+@item
+MSYS Developer Tool Kit - msys-autoconf (bin)
+
+@item
+MSYS Developer Tool Kit - msys-automake (bin)
+
+@item
+MinGW Runtime
+
+@item
+MinGW Utilities
+
+@item
+Windows API
+
+@item
+Binutils
+
+@item
+make
+
+@item
+pdcurses
+
+@item
+GDB (snapshot)
+@end itemize
+
+@itemize @bullet
+
+
+@item
+Install MSYS (to c:\mingw, for example.)@
+Do @strong{not} use spaces in the pathname (c:\program files\mingw).
+
+@item
+Install MinGW runtime, utilities and GCC to a subdirectory (to c:\mingw\mingw,
+for example)
+
+@item
+Install the Development Kit to the MSYS directory (c:\mingw)
+
+@item
+Create a batch file bash.bat in your MSYS directory with the files:@
+
+@example
+bin\sh.exe --login
+@end example
+
+
+This batch file opens a shell which is used to invoke the build processes..@
+MinGW's standard shell (msys.bat) is not suitable because it opens a separate
+console window@ On Vista, bash.bat needs to be run as administrator.
+
+@item
+Start bash.sh and rename (c:\mingw\mingw\)lib\libstdc++.la to avoid problems:@
+
+@example
+mv /usr/mingw/lib/libstdc++.la /usr/mingw/lib/libstdc++.la.broken
+@end example
+
+
+@item
+Unpack the Windows API to the MinGW directory (c:\mingw\mingw\) and remove the
+declaration of DATADIR from (c:\mingw\mingw\)include\objidl.h (lines 55-58)
+
+@item
+Unpack autoconf, automake to the MSYS directory (c:\mingw)
+
+@item
+Install all other packages to the MinGW directory (c:\mingw\mingw\)
+@end itemize
+
+
+@item
+@strong{GNU Libtool}@
+@
+GNU Libtool is required to use shared libraries.@
+@
+Get the prebuilt package from here and unpack it to the MinGW directory
+(c:\mingw)
+
+@item
+@strong{Pthreads}@
+@
+GNUnet uses the portable POSIX thread library for multi-threading..@
+
+@itemize @bullet
+
+
+@item
+Save @uref{ftp://sources.redhat.com/pub/pthreads-win32/dll-latest/lib/x86
+/libpthreadGC2.a, libpthreadGC2.a} (x86) or @uref{ftp://sources.redhat.c
+om/pub/pthreads-win32/dll-latest/lib/x64/libpthreadGC2.a, libpthreadGC2.
+a} (x64) as libpthread.a into the lib directory (c:\mingw\mingw\lib\libpt
+hread.a)
+
+@item
+Save @uref{ftp://sources.redhat.com/pub/pthreads-win32/dll-latest/lib/x86
+/pthreadGC2.dll, pthreadGC2.dll} (x86) or @uref{ftp://sources.redhat.c
+om/pub/pthreads-win32/dll-latest/lib/x64/pthreadGC2.dll, libpthreadGC2.a}
+(x64) into the MinGW bin directory (c:\mingw\mingw\bin)
+
+@item
+Download all header files from @uref{ftp://sources.redhat.com/pub/pthread
+s-win32/dll-latest/include/, include/} to the @file{include} directory
+(c:\mingw\mingw\include)
+@end itemize
+
+
+@item
+@strong{GNU MP@
+}@
+@
+GNUnet uses the GNU Multiple Precision library for special cryptographic operations.@
+@
+Get the GMP binary package from the
+@uref{http://sourceforge.net/projects/mingwrep/, MinGW repository} and
+unpack it to the MinGW directory (c:\mingw\mingw)
+
+@item
+@strong{GNU Gettext}@
+@
+ GNU gettext is used to provide national language support.@
+@
+ Get the prebuilt package from hereand unpack it to the MinGW directory (c:\mingw\mingw)
+
+@item
+@strong{GNU iconv}@
+@
+ GNU Libiconv is used for character encoding conversion.@
+@
+ Get the prebuilt package from here and unpack it to the MinGW directory (c:\mingw\mingw)
+
+@item
+@strong{SQLite}@
+@
+ GNUnet uses the SQLite database to store data.@
+@
+ Get the prebuilt binary from here and unpack it to your MinGW directory.
+
+@item @strong{MySQL}@
+As an alternative to SQLite, GNUnet also supports MySQL.
+
+@itemize @bullet
+
+@item Get the binary installer from the
+@uref{http://dev.mysql.com/downloads/mysql/4.1.html#Windows, MySQL project}
+(version 4.1), install it and follow the instructions in README.mysql.
+
+@item Create a temporary build directory (c:\mysql)
+
+@item Copy the directories include\ and lib\ from the MySQL directory to
+the new directory
+
+@item Get the patches from
+@uref{http://bugs.mysql.com/bug.php?id=8906&files=1, Bug #8906} and
+@uref{http://bugs.mysql.com/bug.php?id=8872&files=1, Bug #8872} (the
+latter is only required for MySQL
+
+@example
+patch -p 0
+@end example
+
+@item Move lib\opt\libmysql.dll to lib\libmysql.dll
+
+@item Change to lib\ and create an import library:@
+
+@example
+dlltool --input-def ../include/libmySQL.def --dllname libmysql.dll
+ --output-lib libmysqlclient.a -k
+@end example
+
+@item Copy include\* to include\mysql\
+
+@item Pass "--with-mysql=/c/mysql" to ./configure and copy libmysql.dll
+to your PATH or GNUnet's @file{bin} directory
+@end itemize
+
+
+@item
+@strong{GTK+}@
+@
+ gnunet-gtk and libextractor depend on GTK.@
+@
+ Get the the binary and developer packages of atk, glib, gtk, iconv,
+ gettext-runtime, pango from
+ @uref{ftp://ftp.gtk.org/pub/gtk/v2.6/win32, gtk.org} and unpack it to the
+ MinGW directory (c:\mingw\mingw)@
+@
+ Get @uref{http://www.gtk.org/download/win32.php, pkg-config} and libpng
+ and unpack them to the MinGW directory (c:\mingw\mingw)@
+@
+ Here is an all-in-one package for
+ @uref{http://ftp.gnome.org/pub/gnome/binaries/win32/gtk+/2.24/gtk+-bundle_2.24.10-20120208_win32.zip, gtk+dependencies}.
+ Do not overwrite any existing files!
+
+@item
+@strong{Glade}@
+@
+ gnunet-gtk and and gnunet-setup were created using this interface builder
+
+@itemize @bullet
+
+
+@item
+ Get the Glade and libglade (-bin and -devel) packages (without GTK!) from
+ @uref{http://gladewin32.sourceforge.net/, GladeWin32} and unpack it to
+ the MinGW directory (c:\mingw\mingw)
+
+@item
+Get libxml from here and unpack it to the MinGW
+directory (c:\mingw\mingw).
+@end itemize
+
+
+@item
+@strong{zLib}@
+@
+libextractor requires zLib to decompress some file formats. GNUnet uses it
+to (de)compress meta-data.@
+@
+ Get zLib from here (Signature) and unpack it to the
+ MinGW directory (c:\mingw\mingw)
+
+@item
+@strong{Bzip2}@
+@
+ libextractor also requires Bzip2 to decompress some file formats.@
+@
+Get Bzip2 (binary and developer package) from
+@uref{http://gnuwin32.sourceforge.net/packages/bzip2.htm, GnuWin32} and
+unpack it to the MinGW directory (c:\mingw\mingw)
+
+@item
+@strong{Libgcrypt}@
+@
+ Libgcrypt provides the cryptographic functions used by GNUnet@
+@
+ Get Libgcrypt from @uref{ftp://ftp.gnupg.org/gcrypt/libgcrypt/, here},
+ compile and place it in the MinGW directory (c:\mingw\mingw). Currently
+ you need at least version 1.4.2 to compile GNUnet.
+
+@item
+@strong{PlibC}@
+@
+ PlibC emulates Unix functions under Windows.@
+@
+ Get PlibC from here and unpack it to the MinGW
+ directory (c:\mingw\mingw)
+
+@item
+@strong{OGG Vorbis}@
+@
+ OGG Vorbis is used to extract meta-data from .ogg files@
+@
+ Get the packages
+ @uref{http://www.gnunet.org/libextractor/download/win/libogg-1.1.4.zip, libogg}
+ and
+ @uref{http://www.gnunet.org/libextractor/download/win/libvorbis-1.2.3.zip, libvorbis}
+ from the
+ @uref{http://ftp.gnu.org/gnu/libextractor/libextractor-w32-1.0.0.zip, libextractor win32 build}
+ and unpack them to the MinGW directory (c:\mingw\mingw)
+
+@item
+@strong{Exiv2}@
+@
+ (lib)Exiv2 is used to extract meta-data from files with Exiv2 meta-data@
+@
+ Download
+@uref{http://www.gnunet.org/libextractor/download/win/exiv2-0.18.2.zip, Exiv2}
+and unpack it to the MSYS directory (c:\mingw)
+@end itemize
+
+@node Building libextractor and GNUnet
+@subsubsection Building libextractor and GNUnet
+
+Before you compile libextractor or GNUnet, be sure to set PKG_CONFIG_PATH:
+
+@example
+export PKG_CONFIG_PATH=/mingw/lib/pkgconfig
+@end example
+
+@noindent
+See Installation for basic instructions on building libextractor
+and GNUnet. By default, all modules that are created in this way contain
+debug information and are quite large. To compile release versions (small
+and fast) set the variable CFLAGS:
+
+@example
+export CFLAGS='-O2 -march=pentium -fomit-frame-pointer'
+./configure --prefix=$HOME --with-extractor=$HOME
+@end example
+
+@node Installer
+@subsubsection Installer
+
+The GNUnet installer is made with
+@uref{http://nsis.sourceforge.net/, NSIS}. The installer script is
+located in @file{contrib\win} in the GNUnet source tree.
+
+@node Source
+@subsubsection Source
+
+The sources of all dependencies are available here.
+
+@node Portable GNUnet
+@section Portable GNUnet
+
+Quick instructions on how to use the most recent GNUnet on most GNU/Linux
+distributions
+
+Currently this has only been tested on Ubuntu 12.04, 12.10, 13.04, Debian
+and CentOS 6, but it should work on almost any GNU/Linux distribution.
+More in-detail information can be found in the handbook.
+
+
+
+@menu
+* Prerequisites::
+* Download & set up gnunet-update::
+* Install GNUnet::
+@end menu
+
+@node Prerequisites
+@subsection Prerequisites
+
+Open a terminal and paste this line into it to install all required tools
+needed:@
+@code{sudo apt-get install python-gpgme subversion}
+
+@node Download & set up gnunet-update
+@subsection Download & set up gnunet-update
+
+The following command will download a working version of gnunet-update
+with the subversion tool and import the public key which is needed for
+authentication:
+
+@example
+svn checkout -r24905 https://gnunet.org/svn/gnunet-update ~/gnunet-update
+cd ~/gnunet-update
+gpg --keyserver "hkp://keys.gnupg.net" --recv-keys 7C613D78
+@end example
+
+@node Install GNUnet
+@subsection Install GNUnet
+
+Download and install GNUnet binaries which can be found here and set
+library paths:
+
+@example
+wget -P /tmp https://gnunet.org/install/packs/gnunet-0.9.4-`uname -m`.tgz
+./bin/gnunet-update install /tmp/gnunet-0.9*.tgz ~
+echo "PATH DEFAULT=$@{PATH@}:$HOME/bin" >> ~/.pam_environment
+echo -e "$@{HOME@}/lib\n$@{HOME@}/lib/gnunet-deps" | sudo tee \
+ /etc/ld.so.conf.d/gnunet.conf > /dev/null
+sudo ldconfig
+@end example
+
+You may need to re-login once after executing these last commands
+
+That's it, GNUnet is installed in your home directory now. GNUnet can be
+configured and afterwards started by executing @code{gnunet-arm -s}.
+
+@node The graphical configuration interface
+@section The graphical configuration interface
+
+If you also would like to use gnunet-gtk and gnunet-setup (highly
+recommended for beginners), do:
+
+@example
+wget -P /tmp https://gnunet.org/install/packs/gnunet-0.9.4-gtk-0.9.4-`uname -m`.tgz
+sh ~/gnunet-update/bin/gnunet-update install /tmp/gnunet-*gtk*.tgz ~
+sudo ldconfig
+@end example
+
+Now you can run @code{gnunet-setup} for easy configuration of your
+GNUnet peer.
+
+@menu
+* Configuring your peer::
+* Configuring the Friend-to-Friend (F2F) mode::
+* Configuring the hostlist to bootstrap::
+* Configuration of the HOSTLIST proxy settings::
+* Configuring your peer to provide a hostlist ::
+* Configuring the datastore::
+* Configuring the MySQL database::
+* Reasons for using MySQL::
+* Reasons for not using MySQL::
+* Setup Instructions::
+* Testing::
+* Performance Tuning::
+* Setup for running Testcases::
+* Configuring the Postgres database::
+* Reasons to use Postgres::
+* Reasons not to use Postgres::
+* Manual setup instructions::
+* Testing the setup manually::
+* Configuring the datacache::
+* Configuring the file-sharing service::
+* Configuring logging::
+* Configuring the transport service and plugins::
+* Configuring the wlan transport plugin::
+* Configuring HTTP(S) reverse proxy functionality using Apache or nginx::
+* Blacklisting peers::
+* Configuration of the HTTP and HTTPS transport plugins::
+* Configuring the GNU Name System::
+* Configuring the GNUnet VPN::
+* Bandwidth Configuration::
+* Configuring NAT::
+* Peer configuration for distributions::
+@end menu
+
+@node Configuring your peer
+@subsection Configuring your peer
+
+This chapter will describe the various configuration options in GNUnet.
+
+The easiest way to configure your peer is to use the gnunet-setup tool.
+gnunet-setup is part of the gnunet-gtk download. You might have to
+install it separately.
+
+Many of the specific sections from this chapter actually are linked from
+within gnunet-setup to help you while using the setup tool.
+
+While you can also configure your peer by editing the configuration
+file by hand, this is not recommended for anyone except for developers.
+
+
+@node Configuring the Friend-to-Friend (F2F) mode
+@subsection Configuring the Friend-to-Friend (F2F) mode
+
+GNUnet knows three basic modes of operation. In standard "peer-to-peer"
+mode, your peer will connect to any peer. In the pure "friend-to-friend"
+mode, your peer will ONLY connect to peers from a list of friends
+specified in the configuration.
+Finally, in mixed mode, GNUnet will only connect to arbitrary peers if it
+has at least a specified number of connections to friends.
+
+When configuring any of the F2F modes, you first need to create a file
+with the peer identities of your friends. Ask your friends to run
+
+@example
+$ gnunet-peerinfo -sq
+@end example
+
+@noindent
+The output of this command needs to be added to your friends file, which
+is simply a plain text file with one line per friend with the output from
+the above command.
+
+You then specify the location of your friends file in the "FRIENDS"
+option of the "topology" section.
+
+Once you have created the friends file, you can tell GNUnet to only
+connect to your friends by setting the "FRIENDS-ONLY" option (again in
+the "topology" section) to YES.
+
+If you want to run in mixed-mode, set "FRIENDS-ONLY" to NO and configure a
+minimum number of friends to have (before connecting to arbitrary peers)
+under the "MINIMUM-FRIENDS" option.
+
+If you want to operate in normal P2P-only mode, simply set
+"MINIMUM-FRIENDS" to zero and "FRIENDS_ONLY" to NO. This is the default.
+
+@node Configuring the hostlist to bootstrap
+@subsection Configuring the hostlist to bootstrap
+
+After installing the software you need to get connected to the GNUnet
+network. The configuration file included in your download is already
+configured to connect you to the GNUnet network.
+In this section the relevant configuration settings are explained.
+
+To get an initial connection to the GNUnet network and to get to know
+peers already connected to the network you can use the so called
+bootstrap servers.
+These servers can give you a list of peers connected to the network.
+To use these bootstrap servers you have to configure the hostlist daemon
+to activate bootstrapping.
+
+To activate bootstrapping edit your configuration file and edit the
+@code{[hostlist]}-section. You have to set the argument "-b" in the
+options line:
+
+@example
+[hostlist]
+OPTIONS = -b
+@end example
+
+Additionally you have to specify which server you want to use.
+The default bootstrapping server is
+"@uref{http://v10.gnunet.org/hostlist, http://v10.gnunet.org/hostlist}".
+[^] To set the server you have to edit the line "SERVERS" in the hostlist
+section. To use the default server you should set the lines to
+
+@example
+SERVERS = http://v10.gnunet.org/hostlist [^]
+@end example
+
+@noindent
+To use bootstrapping your configuration file should include these lines:
+
+@example
+[hostlist]
+OPTIONS = -b
+SERVERS = http://v10.gnunet.org/hostlist [^]
+@end example
+
+@noindent
+Besides using bootstrap servers you can configure your GNUnet peer to
+recieve hostlist advertisements.
+Peers offering hostlists to other peers can send advertisement messages
+to peers that connect to them. If you configure your peer to receive these
+messages, your peer can download these lists and connect to the peers
+included. These lists are persistent, which means that they are saved to
+your hard disk regularly and are loaded during startup.
+
+To activate hostlist learning you have to add the "-e" switch to the
+OPTIONS line in the hostlist section:
+
+@example
+[hostlist]
+OPTIONS = -b -e
+@end example
+
+@noindent
+Furthermore you can specify in which file the lists are saved. To save the
+lists in the file "hostlists.file" just add the line:
+
+@example
+HOSTLISTFILE = hostlists.file
+@end example
+
+@noindent
+Best practice is to activate both bootstrapping and hostlist learning.
+So your configuration file should include these lines:
+
+@example
+[hostlist]
+OPTIONS = -b -e
+HTTPPORT = 8080
+SERVERS = http://v10.gnunet.org/hostlist [^]
+HOSTLISTFILE = $SERVICEHOME/hostlists.file
+@end example
+
+@node Configuration of the HOSTLIST proxy settings
+@subsection Configuration of the HOSTLIST proxy settings
+
+The hostlist client can be configured to use a proxy to connect to the
+hostlist server.
+This functionality can be configured in the configuration file directly
+or using the gnunet-setup tool.
+
+The hostlist client supports the following proxy types at the moment:
+
+@itemize @bullet
+@item HTTP and HTTP 1.0 only proxy
+@item SOCKS 4/4a/5/5 with hostname
+@end itemize
+
+In addition authentication at the proxy with username and password can be
+configured.
+
+To configure proxy support for the hostlist client in the gnunet-setup
+tool, select the "hostlist" tab and select the appropriate proxy type.
+The hostname or IP address (including port if required) has to be entered
+in the "Proxy hostname" textbox. If required, enter username and password
+in the "Proxy username" and "Proxy password" boxes.
+Be aware that these information will be stored in the configuration in
+plain text.
+
+To configure these options directly in the configuration, you can
+configure the following settings in the
+@code{[hostlist]} section of the configuration:
+
+@example
+ # Type of proxy server,@
+ # Valid values: HTTP, HTTP_1_0, SOCKS4, SOCKS5, SOCKS4A, SOCKS5_HOSTNAME@
+ # Default: HTTP@
+ # PROXY_TYPE = HTTP
+
+# Hostname or IP of proxy server@
+ # PROXY =@
+ # User name for proxy server@
+ # PROXY_USERNAME =@
+ # User password for proxy server@
+ # PROXY_PASSWORD =@
+@end example
+
+@node Configuring your peer to provide a hostlist
+@subsection Configuring your peer to provide a hostlist
+
+If you operate a peer permanently connected to GNUnet you can configure
+your peer to act as a hostlist server, providing other peers the list of
+peers known to him.
+
+Yor server can act as a bootstrap server and peers needing to obtain a
+list of peers can contact him to download this list.
+To download this hostlist the peer uses HTTP.
+For this reason you have to build your peer with libcurl and microhttpd
+support. How you build your peer with this options can be found here:
+@uref{https://gnunet.org/generic_installation}
+
+To configure your peer to act as a bootstrap server you have to add the
+"@code{-p}" option to OPTIONS in the @code{[hostlist]} section of your
+configuration file. Besides that you have to specify a port number for
+the http server. In conclusion you have to add the following lines:
+
+@example
+[hostlist]
+HTTPPORT = 12980
+OPTIONS = -p
+@end example
+
+@noindent
+If your peer acts as a bootstrap server other peers should know about
+that. You can advertise the hostlist your are providing to other peers.
+Peers connecting to your peer will get a message containing an
+advertisement for your hostlist and the URL where it can be downloaded.
+If this peer is in learning mode, it will test the hostlist and, in the
+case it can obtain the list successfully, it will save it for
+bootstrapping.
+
+To activate hostlist advertisement on your peer, you have to set the
+following lines in your configuration file:
+
+@example
+[hostlist]
+EXTERNAL_DNS_NAME = example.org
+HTTPPORT = 12981
+OPTIONS = -p -a
+@end example
+
+@noindent
+With this configuration your peer will a act as a bootstrap server and
+advertise this hostlist to other peers connecting to him. The URL used to
+download the list will be
+@code{@uref{http://example.org:12981/, http://example.org:12981/}}.
+
+Please notice:
+@itemize @bullet
+@item The hostlist is not human readable, so you should not try to
+download it using your webbrowser. Just point your GNUnet peer to the
+address!
+@item Advertising without providing a hostlist does not make sense and
+will not work.
+@end itemize
+
+@node Configuring the datastore
+@subsection Configuring the datastore
+
+The datastore is what GNUnet uses to for long-term storage of file-sharing
+data. Note that long-term does not mean 'forever' since content does have
+an expiration date, and of course storage space is finite (and hence
+sometimes content may have to be discarded).
+
+Use the "QUOTA" option to specify how many bytes of storage space you are
+willing to dedicate to GNUnet.
+
+In addition to specifying the maximum space GNUnet is allowed to use for
+the datastore, you need to specify which database GNUnet should use to do
+so. Currently, you have the choice between sqLite, MySQL and Postgres.
+
+@node Configuring the MySQL database
+@subsection Configuring the MySQL database
+
+This section describes how to setup the MySQL database for GNUnet.
+
+Note that the mysql plugin does NOT work with mysql before 4.1 since we
+need prepared statements.
+We are generally testing the code against MySQL 5.1 at this point.
+
+@node Reasons for using MySQL
+@subsection Reasons for using MySQL
+
+@itemize @bullet
+
+@item
+On up-to-date hardware where mysql can be used comfortably, this module
+will have better performance than the other database choices (according
+to our tests).
+
+@item Its often possible to recover the mysql database from internal
+inconsistencies. Some of the other databases do not support repair.
+@end itemize
+
+@node Reasons for not using MySQL
+@subsection Reasons for not using MySQL
+
+@itemize @bullet
+@item Memory usage (likely not an issue if you have more than 1 GB)
+@item Complex manual setup
+@end itemize
+
+@node Setup Instructions
+@subsection Setup Instructions
+
+@itemize @bullet
+@item In @code{gnunet.conf} set in section "DATASTORE" the value for
+"DATABASE" to "mysql".
+@item Access mysql as root:@
+
+@example
+$ mysql -u root -p
+@end example
+
+@noindent
+and issue the following commands, replacing $USER with the username
+that will be running gnunet-arm (so typically "gnunet"):
+
+@example
+CREATE DATABASE gnunet;
+GRANT select,insert,update,delete,create,alter,drop,create temporary tables
+ ON gnunet.* TO $USER@@localhost;
+SET PASSWORD FOR $USER@@localhost=PASSWORD('$the_password_you_like');
+FLUSH PRIVILEGES;
+@end example
+
+@item
+In the $HOME directory of $USER, create a ".my.cnf" file with the
+following lines
+
+@example
+[client]
+user=$USER
+password=$the_password_you_like
+@end example
+
+@end itemize
+
+Thats it. Note that @code{.my.cnf} file is a slight security risk unless
+its on a safe partition. The $HOME/.my.cnf can of course be a symbolic
+link. Luckily $USER has only priviledges to mess up GNUnet's tables,
+which should be pretty harmless.
+
+@node Testing
+@subsection Testing
+
+You should briefly try if the database connection works. First, login
+as $USER. Then use:
+
+@example
+$ mysql -u $USER
+mysql> use gnunet;
+@end example
+
+@noindent
+If you get the message "Database changed" it probably works.
+
+If you get "ERROR 2002: Can't connect to local MySQL server@
+through socket '/tmp/mysql.sock' (2)" it may be resolvable by@
+"ln -s /var/run/mysqld/mysqld.sock /tmp/mysql.sock"@
+so there may be some additional trouble depending on your mysql setup.
+
+@node Performance Tuning
+@subsection Performance Tuning
+
+For GNUnet, you probably want to set the option
+
+@example
+innodb_flush_log_at_trx_commit = 0
+@end example
+
+@noindent
+for a rather dramatic boost in MySQL performance. However, this reduces
+the "safety" of your database as with this options you may loose
+transactions during a power outage.
+While this is totally harmless for GNUnet, the option applies to all
+applications using MySQL. So you should set it if (and only if) GNUnet is
+the only application on your system using MySQL.
+
+@node Setup for running Testcases
+@subsection Setup for running Testcases
+
+If you want to run the testcases, you must create a second database
+"gnunetcheck" with the same username and password. This database will
+then be used for testing ("make check").
+
+@node Configuring the Postgres database
+@subsection Configuring the Postgres database
+
+This text describes how to setup the Postgres database for GNUnet.
+
+This Postgres plugin was developed for Postgres 8.3 but might work for
+earlier versions as well.
+
+@node Reasons to use Postgres
+@subsection Reasons to use Postgres
+
+@itemize @bullet
+@item Easier to setup than MySQL
+@item Real database
+@end itemize
+
+@node Reasons not to use Postgres
+@subsection Reasons not to use Postgres
+
+@itemize @bullet
+@item Quite slow
+@item Still some manual setup required
+@end itemize
+
+@node Manual setup instructions
+@subsection Manual setup instructions
+
+@itemize @bullet
+@item In @code{gnunet.conf} set in section "DATASTORE" the value for
+"DATABASE" to "postgres".
+@item Access Postgres to create a user:@
+
+@table @asis
+@item with Postgres 8.x, use:
+
+@example
+# su - postgres
+$ createuser
+@end example
+
+@noindent
+and enter the name of the user running GNUnet for the role interactively.
+Then, when prompted, do not set it to superuser, allow the creation of
+databases, and do not allow the creation of new roles.@
+
+@item with Postgres 9.x, use:
+
+@example
+# su - postgres
+$ createuser -d $GNUNET_USER
+@end example
+
+@noindent
+where $GNUNET_USER is the name of the user running GNUnet.@
+
+@end table
+
+
+@item
+As that user (so typically as user "gnunet"), create a database (or two):@
+
+@example
+$ createdb gnunet
+# this way you can run "make check"
+$ createdb gnunetcheck
+@end example
+
+@end itemize
+
+Now you should be able to start @code{gnunet-arm}.
+
+@node Testing the setup manually
+@subsection Testing the setup manually
+
+You may want to try if the database connection works. First, again login
+as the user who will run gnunet-arm. Then use,
+
+@example
+$ psql gnunet # or gnunetcheck
+gnunet=> \dt
+@end example
+
+@noindent
+If, after you have started gnunet-arm at least once, you get
+a @code{gn090} table here, it probably works.
+
+@node Configuring the datacache
+@subsection Configuring the datacache
+@c %**end of header
+
+The datacache is what GNUnet uses for storing temporary data. This data is
+expected to be wiped completely each time GNUnet is restarted (or the
+system is rebooted).
+
+You need to specify how many bytes GNUnet is allowed to use for the
+datacache using the "QUOTA" option in the section "dhtcache".
+Furthermore, you need to specify which database backend should be used to
+store the data. Currently, you have the choice between
+sqLite, MySQL and Postgres.
+
+@node Configuring the file-sharing service
+@subsection Configuring the file-sharing service
+
+In order to use GNUnet for file-sharing, you first need to make sure
+that the file-sharing service is loaded.
+This is done by setting the AUTOSTART option in section "fs" to "YES".
+Alternatively, you can run
+
+@example
+$ gnunet-arm -i fs
+@end example
+
+@noindent
+to start the file-sharing service by hand.
+
+Except for configuring the database and the datacache the only important
+option for file-sharing is content migration.
+
+Content migration allows your peer to cache content from other peers as
+well as send out content stored on your system without explicit requests.
+This content replication has positive and negative impacts on both system
+performance and privacy.
+
+FIXME: discuss the trade-offs. Here is some older text about it...
+
+Setting this option to YES allows gnunetd to migrate data to the local
+machine. Setting this option to YES is highly recommended for efficiency.
+Its also the default. If you set this value to YES, GNUnet will store
+content on your machine that you cannot decrypt.
+While this may protect you from liability if the judge is sane, it may
+not (IANAL). If you put illegal content on your machine yourself, setting
+this option to YES will probably increase your chances to get away with it
+since you can plausibly deny that you inserted the content.
+Note that in either case, your anonymity would have to be broken first
+(which may be possible depending on the size of the GNUnet network and the
+strength of the adversary).
+
+@node Configuring logging
+@subsection Configuring logging
+
+Logging in GNUnet 0.9.0 is controlled via the "-L" and "-l" options.
+Using "-L", a log level can be specified. With log level "ERROR" only
+serious errors are logged.
+The default log level is "WARNING" which causes anything of
+concern to be logged. Log level "INFO" can be used to log anything that
+might be interesting information whereas "DEBUG" can be used by
+developers to log debugging messages (but you need to run configure with
+@code{--enable-logging=verbose} to get them compiled).
+The "-l" option is used to specify the log file.
+
+Since most GNUnet services are managed by @code{gnunet-arm}, using the
+"-l" or "-L" options directly is not possible.
+Instead, they can be specified using the "OPTIONS" configuration value in
+the respective section for the respective service.
+In order to enable logging globally without editing the "OPTIONS" values
+for each service, @code{gnunet-arm} supports a "GLOBAL_POSTFIX" option.
+The value specified here is given as an extra option to all services for
+which the configuration does contain a service-specific "OPTIONS" field.
+
+"GLOBAL_POSTFIX" can contain the special sequence "@{@}" which is replaced
+by the name of the service that is being started. Furthermore,
+@code{GLOBAL_POSTFIX} is special in that sequences starting with "$"
+anywhere in the string are expanded (according to options in "PATHS");
+this expansion otherwise is only happening for filenames and then the "$"
+must be the first character in the option. Both of these restrictions do
+not apply to "GLOBAL_POSTFIX".
+Note that specifying @code{%} anywhere in the "GLOBAL_POSTFIX" disables
+both of these features.
+
+In summary, in order to get all services to log at level "INFO" to
+log-files called @code{SERVICENAME-logs}, the following global prefix
+should be used:
+
+@example
+GLOBAL_POSTFIX = -l $SERVICEHOME/@{@}-logs -L INFO
+@end example
+
+@node Configuring the transport service and plugins
+@subsection Configuring the transport service and plugins
+
+The transport service in GNUnet is responsible to maintain basic
+connectivity to other peers.
+Besides initiating and keeping connections alive it is also responsible
+for address validation.
+
+The GNUnet transport supports more than one transport protocol.
+These protocols are configured together with the transport service.
+
+The configuration section for the transport service itself is quite
+similar to all the other services
+
+@example
+ AUTOSTART = YES@
+ @@UNIXONLY@@ PORT = 2091@
+ HOSTNAME = localhost@
+ HOME = $SERVICEHOME@
+ CONFIG = $DEFAULTCONFIG@
+ BINARY = gnunet-service-transport@
+ #PREFIX = valgrind@
+ NEIGHBOUR_LIMIT = 50@
+ ACCEPT_FROM = 127.0.0.1;@
+ ACCEPT_FROM6 = ::1;@
+ PLUGINS = tcp udp@
+ UNIXPATH = /tmp/gnunet-service-transport.sock@
+@end example
+
+Different are the settings for the plugins to load @code{PLUGINS}.
+The first setting specifies which transport plugins to load.
+
+@itemize @bullet
+@item transport-unix
+A plugin for local only communication with UNIX domain sockets. Used for
+testing and available on unix systems only. Just set the port
+
+@example
+ [transport-unix]@
+ PORT = 22086@
+ TESTING_IGNORE_KEYS = ACCEPT_FROM;@
+@end example
+
+@item transport-tcp
+A plugin for communication with TCP. Set port to 0 for client mode with
+outbound only connections
+
+@example
+ [transport-tcp]@
+ # Use 0 to ONLY advertise as a peer behind NAT (no port binding)@
+ PORT = 2086@
+ ADVERTISED_PORT = 2086@
+ TESTING_IGNORE_KEYS = ACCEPT_FROM;@
+ # Maximum number of open TCP connections allowed@
+ MAX_CONNECTIONS = 128@
+@end example
+
+@item transport-udp
+A plugin for communication with UDP. Supports peer discovery using
+broadcasts.
+
+@example
+ [transport-udp]@
+ PORT = 2086@
+ BROADCAST = YES@
+ BROADCAST_INTERVAL = 30 s@
+ MAX_BPS = 1000000@
+ TESTING_IGNORE_KEYS = ACCEPT_FROM;@
+@end example
+
+@item transport-http
+HTTP and HTTPS support is split in two part: a client plugin initiating
+outbound connections and a server part accepting connections from the
+client. The client plugin just takes the maximum number of connections as
+an argument.
+
+@example
+ [transport-http_client]@
+ MAX_CONNECTIONS = 128@
+ TESTING_IGNORE_KEYS = ACCEPT_FROM;@
+@end example
+
+@example
+ [transport-https_client]@
+ MAX_CONNECTIONS = 128@
+ TESTING_IGNORE_KEYS = ACCEPT_FROM;@
+@end example
+
+@noindent
+The server has a port configured and the maximum nunber of connections.
+The HTTPS part has two files with the certificate key and the certificate
+file.
+
+The server plugin supports reverse proxies, so a external hostname can be
+set using the @code{EXTERNAL_HOSTNAME} setting.
+The webserver under this address should forward the request to the peer
+and the configure port.
+
+@example
+ [transport-http_server]@
+ EXTERNAL_HOSTNAME = fulcrum.net.in.tum.de/gnunet@
+ PORT = 1080@
+ MAX_CONNECTIONS = 128@
+ TESTING_IGNORE_KEYS = ACCEPT_FROM;@
+@end example
+
+@example
+ [transport-https_server]@
+ PORT = 4433@
+ CRYPTO_INIT = NORMAL@
+ KEY_FILE = https.key@
+ CERT_FILE = https.cert@
+ MAX_CONNECTIONS = 128@
+ TESTING_IGNORE_KEYS = ACCEPT_FROM;@
+@end example
+
+@item transport-wlan
+
+There is a special article how to setup the WLAN plugin, so here only the
+settings. Just specify the interface to use:
+
+@example
+ [transport-wlan]@
+ # Name of the interface in monitor mode (typically monX)@
+ INTERFACE = mon0@
+ # Real hardware, no testing@
+ TESTMODE = 0@
+ TESTING_IGNORE_KEYS = ACCEPT_FROM;@
+@end example
+@end itemize
+
+@node Configuring the wlan transport plugin
+@subsection Configuring the wlan transport plugin
+
+
+The wlan transport plugin enables GNUnet to send and to receive data on a
+wlan interface.
+It has not to be connected to a wlan network as long as sender and
+receiver are on the same channel. This enables you to get connection to
+the GNUnet where no internet access is possible, for example while
+catastrophes or when censorship cuts you off the internet.
+
+
+@menu
+* Requirements for the WLAN plugin::
+* Configuration::
+* Before starting GNUnet::
+* Limitations and known bugs::
+@end menu
+
+
+@node Requirements for the WLAN plugin
+@subsubsection Requirements for the WLAN plugin
+
+@itemize @bullet
+
+@item wlan network card with monitor support and packet injection
+(see @uref{http://www.aircrack-ng.org/, aircrack-ng.org})
+
+@item Linux kernel with mac80211 stack, introduced in 2.6.22, tested with
+2.6.35 and 2.6.38
+
+@item Wlantools to create the a monitor interface, tested with airmon-ng
+of the aircrack-ng package
+@end itemize
+
+@node Configuration
+@subsubsection Configuration
+
+There are the following options for the wlan plugin (they should be like
+this in your default config file, you only need to adjust them if the
+values are incorrect for your system)
+
+@example
+# section for the wlan transport plugin@
+[transport-wlan]@
+# interface to use, more information in the
+# "Before starting GNUnet" section of the handbook.
+INTERFACE = mon0@
+# testmode for developers:@
+# 0 use wlan interface,@
+#1 or 2 use loopback driver for tests 1 = server, 2 = client@
+TESTMODE = 0@
+@end example
+
+@node Before starting GNUnet
+@subsubsection Before starting GNUnet
+
+Before starting GNUnet, you have to make sure that your wlan interface is
+in monitor mode. One way to put the wlan interface into monitor mode (if
+your interface name is wlan0) is by executing:
+
+@example
+ sudo airmon-ng start wlan0@
+@end example
+
+@noindent
+Here is an example what the result should look like:
+
+@example
+ Interface Chipset Driver@
+ wlan0 Intel 4965 a/b/g/n iwl4965 - [phy0]@
+ (monitor mode enabled on mon0)@
+@end example
+
+@noindent
+The monitor interface is mon0 is the one that you have to put into the
+configuration file.
+
+@node Limitations and known bugs
+@subsubsection Limitations and known bugs
+
+Wlan speed is at the maximum of 1 Mbit/s because support for choosing the
+wlan speed with packet injection was removed in newer kernels.
+Please pester the kernel developers about fixing this.
+
+The interface channel depends on the wlan network that the card is
+connected to. If no connection has been made since the start of the
+computer, it is usually the first channel of the card.
+Peers will only find each other and communicate if they are on the same
+channel. Channels must be set manually (i.e. using
+@code{iwconfig wlan0 channel 1}).
+
+
+@node Configuring HTTP(S) reverse proxy functionality using Apache or nginx
+@subsection Configuring HTTP(S) reverse proxy functionality using Apache or nginx
+
+The HTTP plugin supports data transfer using reverse proxies. A reverse
+proxy forwards the HTTP request he receives with a certain URL to another
+webserver, here a GNUnet peer.
+
+So if you have a running Apache or nginx webserver you can configure it to
+be a GNUnet reverse proxy. Especially if you have a well-known webiste
+this improves censorship resistance since it looks as normal surfing
+behaviour.
+
+To do so, you have to do two things:
+
+@itemize @bullet
+@item Configure your webserver to forward the GNUnet HTTP traffic
+@item Configure your GNUnet peer to announce the respective address
+@end itemize
+
+As an example we want to use GNUnet peer running:
+
+@itemize @bullet
+
+@item HTTP server plugin on @code{gnunet.foo.org:1080}
+
+@item HTTPS server plugin on @code{gnunet.foo.org:4433}
+
+@item A apache or nginx webserver on
+@uref{http://www.foo.org/, http://www.foo.org:80/}
+
+@item A apache or nginx webserver on https://www.foo.org:443/
+@end itemize
+
+And we want the webserver to accept GNUnet traffic under
+@code{http://www.foo.org/bar/}. The required steps are described here:
+
+@strong{Configure your Apache2 HTTP webserver}
+
+First of all you need mod_proxy installed.
+
+Edit your webserver configuration. Edit
+@code{/etc/apache2/apache2.conf} or the site-specific configuration file.
+
+In the respective @code{server config},@code{virtual host} or
+@code{directory} section add the following lines:
+
+@example
+ ProxyTimeout 300@
+ ProxyRequests Off@
+ <Location /bar/ >@
+ ProxyPass http://gnunet.foo.org:1080/@
+ ProxyPassReverse http://gnunet.foo.org:1080/@
+ </Location>@
+@end example
+
+@noindent
+@strong{Configure your Apache2 HTTPS webserver}
+
+We assume that you already have an HTTPS server running, if not please
+check how to configure a HTTPS host. An easy to use example is the
+@file{apache2/sites-available/default-ssl} example configuration file.
+
+In the respective HTTPS @code{server config},@code{virtual host} or
+@code{directory} section add the following lines:
+
+@example
+ SSLProxyEngine On@
+ ProxyTimeout 300@
+ ProxyRequests Off@
+ <Location /bar/ >@
+ ProxyPass https://gnunet.foo.org:4433/@
+ ProxyPassReverse https://gnunet.foo.org:4433/@
+ </Location>@
+@end example
+
+@noindent
+More information about the apache mod_proxy configuration can be found
+at @uref{http://httpd.apache.org/docs/2.2/mod/mod_proxy.html#proxypass, http://httpd.apache.org/docs/2.2/mod/mod_proxy.html#proxypass}
+
+@strong{Configure your nginx HTTPS webserver}
+
+Since nginx does not support chunked encoding, you first of all have to
+install @code{chunkin}:@
+@uref{http://wiki.nginx.org/HttpChunkinModule, http://wiki.nginx.org/HttpChunkinModule}
+
+To enable chunkin add:
+
+@example
+ chunkin on;@
+ error_page 411 = @@my_411_error;@
+ location @@my_411_error @{@
+ chunkin_resume;@
+ @}@
+@end example
+
+@noindent
+Edit your webserver configuration. Edit @file{/etc/nginx/nginx.conf} or
+the site-specific configuration file.
+
+In the @code{server} section add:@
+
+@example
+ location /bar/@
+ @{@
+ proxy_pass http://gnunet.foo.org:1080/;@
+ proxy_buffering off;@
+ proxy_connect_timeout 5; # more than http_server@
+ proxy_read_timeout 350; # 60 default, 300s is GNUnet's idle timeout@
+ proxy_http_version 1.1; # 1.0 default@
+ proxy_next_upstream error timeout invalid_header http_500 http_503 http_502 http_504;@
+ @}@
+@end example
+
+@noindent
+@strong{Configure your nginx HTTPS webserver}
+
+Edit your webserver configuration. Edit @file{/etc/nginx/nginx.conf} or
+the site-specific configuration file.
+
+In the @code{server} section add:
+
+@example
+ ssl_session_timeout 6m;@
+ location /bar/@
+ @{@
+ proxy_pass https://gnunet.foo.org:4433/;@
+ proxy_buffering off;@
+ proxy_connect_timeout 5; # more than http_server@
+ proxy_read_timeout 350; # 60 default, 300s is GNUnet's idle timeout@
+ proxy_http_version 1.1; # 1.0 default@
+ proxy_next_upstream error timeout invalid_header http_500 http_503 http_502 http_504;@
+ @}@
+@end example
+
+@noindent
+@strong{Configure your GNUnet peer}
+
+To have your GNUnet peer announce the address, you have to specify the
+@code{EXTERNAL_HOSTNAME} option in the @code{[transport-http_server]}
+section:
+
+@example
+ [transport-http_server]@
+ EXTERNAL_HOSTNAME = http://www.foo.org/bar/@
+@end example
+
+@noindent
+and/or @code{[transport-https_server]} section:
+
+@example
+ [transport-https_server]@
+ EXTERNAL_HOSTNAME = https://www.foo.org/bar/@
+@end example
+
+@noindent
+Now restart your webserver and your peer...
+
+@node Blacklisting peers
+@subsection Blacklisting peers
+
+Transport service supports to deny connecting to a specific peer of to a
+specific peer with a specific transport plugin using te blacklisting
+component of transport service. With@ blacklisting it is possible to deny
+connections to specific peers of@ to use a specific plugin to a specific
+peer. Peers can be blacklisted using@ the configuration or a blacklist
+client can be asked.
+
+To blacklist peers using the configuration you have to add a section to
+your@ configuration containing the peer id of the peer to blacklist and
+the plugin@ if required.
+
+Example:@
+
+To blacklist connections to P565... on peer AG2P... using tcp add:@
+
+@c FIXME: This is too long and produces errors in the pdf.
+@example
+ [transport-blacklist AG2PHES1BARB9IJCPAMJTFPVJ5V3A72S3F2A8SBUB8DAQ2V0O3V8G6G2JU56FHGFOHMQVKBSQFV98TCGTC3RJ1NINP82G0RC00N1520]@
+ P565723JO1C2HSN6J29TAQ22MN6CI8HTMUU55T0FUQG4CMDGGEQ8UCNBKUMB94GC8R9G4FB2SF9LDOBAJ6AMINBP4JHHDD6L7VD801G = tcp@
+@end example
+
+To blacklist connections to P565... on peer AG2P... using all plugins add:@
+
+@example
+ [transport-blacklist-AG2PHES1BARB9IJCPAMJTFPVJ5V3A72S3F2A8SBUB8DAQ2V0O3V8G6G2JU56FHGFOHMQVKBSQFV98TCGTC3RJ1NINP82G0RC00N1520]@
+ P565723JO1C2HSN6J29TAQ22MN6CI8HTMUU55T0FUQG4CMDGGEQ8UCNBKUMB94GC8R9G4FB2SF9LDOBAJ6AMINBP4JHHDD6L7VD801G =@
+@end example
+
+You can also add a blacklist client usign the blacklist api. On a
+blacklist check, blacklisting first checks internally if the peer is
+blacklisted and if not, it asks the blacklisting clients. Clients are
+asked if it is OK to connect to a peer ID, the plugin is omitted.
+
+On blacklist check for (peer, plugin)
+@itemize @bullet
+@item Do we have a local blacklist entry for this peer and this plugin?@
+@item YES: disallow connection@
+@item Do we have a local blacklist entry for this peer and all plugins?@
+@item YES: disallow connection@
+@item Does one of the clients disallow?@
+@item YES: disallow connection
+@end itemize
+
+@node Configuration of the HTTP and HTTPS transport plugins
+@subsection Configuration of the HTTP and HTTPS transport plugins
+
+The client part of the http and https transport plugins can be configured
+to use a proxy to connect to the hostlist server. This functionality can
+be configured in the configuration file directly or using the
+gnunet-setup tool.
+
+The both the HTTP and HTTPS clients support the following proxy types at
+the moment:
+
+@itemize @bullet
+@item HTTP 1.1 proxy
+@item SOCKS 4/4a/5/5 with hostname
+@end itemize
+
+In addition authentication at the proxy with username and password can be
+configured.
+
+To configure proxy support for the clients in the gnunet-setup tool,
+select the "transport" tab and activate the respective plugin. Now you
+can select the appropriate proxy type. The hostname or IP address
+(including port if required) has to be entered in the "Proxy hostname"
+textbox. If required, enter username and password in the "Proxy username"
+and "Proxy password" boxes. Be aware that these information will be stored
+in the configuration in plain text.
+
+To configure these options directly in the configuration, you can
+configure the following settings in the [transport-http_client] and
+[transport-https_client] section of the configuration:
+
+@example
+# Type of proxy server,@
+# Valid values: HTTP, SOCKS4, SOCKS5, SOCKS4A, SOCKS5_HOSTNAME@
+# Default: HTTP@
+# PROXY_TYPE = HTTP
+
+# Hostname or IP of proxy server@
+# PROXY =@
+# User name for proxy server@
+# PROXY_USERNAME =@
+# User password for proxy server@
+# PROXY_PASSWORD =
+@end example
+
+@node Configuring the GNU Name System
+@subsection Configuring the GNU Name System
+
+@menu
+* Configuring system-wide DNS interception::
+* Configuring the GNS nsswitch plugin::
+* Configuring GNS on W32::
+* GNS Proxy Setup::
+* Setup of the GNS CA::
+* Testing the GNS setup::
+* Automatic Shortening in the GNU Name System::
+@end menu
+
+
+@node Configuring system-wide DNS interception
+@subsubsection Configuring system-wide DNS interception
+
+Before you install GNUnet, make sure you have a user and group 'gnunet'
+as well as an empty group 'gnunetdns'.
+
+When using GNUnet with system-wide DNS interception, it is absolutely
+necessary for all GNUnet service processes to be started by
+@code{gnunet-service-arm} as user and group 'gnunet'. You also need to be
+sure to run @code{make install} as root (or use the @code{sudo} option to
+configure) to grant GNUnet sufficient privileges.
+
+With this setup, all that is required for enabling system-wide DNS
+interception is for some GNUnet component (VPN or GNS) to request it.
+The @code{gnunet-service-dns} will then start helper programs that will
+make the necessary changes to your firewall (@code{iptables}) rules.
+
+Note that this will NOT work if your system sends out DNS traffic to a
+link-local IPv6 address, as in this case GNUnet can intercept the traffic,
+but not inject the responses from the link-local IPv6 address. Hence you
+cannot use system-wide DNS interception in conjunction with link-local
+IPv6-based DNS servers. If such a DNS server is used, it will bypass
+GNUnet's DNS traffic interception.
+
+Using the GNU Name System (GNS) requires two different configuration
+steps.
+First of all, GNS needs to be integrated with the operating system. Most
+of this section is about the operating system level integration.
+
+Additionally, each individual user who wants to use the system must also
+initialize his GNS zones. This can be done by running (after starting
+GNUnet)
+
+@example
+$ gnunet-gns-import.sh
+@end example
+
+@noindent
+after the local GNUnet peer has been started. Note that the namestore (in
+particular the namestore database backend) should not be reconfigured
+afterwards (as records are not automatically migrated between backends).
+
+The remainder of this chapter will detail the various methods for
+configuring the use of GNS with your operating system.
+
+At this point in time you have different options depending on your OS:
+
+@table @asis
+
+@item Use the gnunet-gns-proxy This approach works for all operating
+systems and is likely the easiest. However, it enables GNS only for
+browsers, not for other applications that might be using DNS, such as SSH.
+Still, using the proxy is required for using HTTP with GNS and is thus
+recommended for all users. To do this, you simply have to run the
+@code{gnunet-gns-proxy-setup-ca} script as the user who will run the
+browser (this will create a GNS certificate authority (CA) on your system
+and import its key into your browser), then start @code{gnunet-gns-proxy}
+and inform your browser to use the Socks5 proxy which
+@code{gnunet-gns-proxy} makes available by default on port 7777.
+@item Use a nsswitch plugin (recommended on GNU systems)
+This approach has the advantage of offering fully personalized resolution
+even on multi-user systems. A potential disadvantage is that some
+applications might be able to bypass GNS.
+@item Use a W32 resolver plugin (recommended on W32)
+This is currently the only option on W32 systems.
+@item Use system-wide DNS packet interception
+This approach is recommended for the GNUnet VPN. It can be used to handle
+GNS at the same time; however, if you only use this method, you will only
+get one root zone per machine (not so great for multi-user systems).
+@end table
+
+You can combine system-wide DNS packet interception with the nsswitch
+plugin.
+The setup of the system-wide DNS interception is described here. All of
+the other GNS-specific configuration steps are described in the following
+sections.
+
+@node Configuring the GNS nsswitch plugin
+@subsubsection Configuring the GNS nsswitch plugin
+
+The Name Service Switch (NSS) is a facility in Unix-like operating systems
+that provides a variety of sources for common configuration databases and
+name resolution mechanisms.
+A system administrator usually configures the operating system's name
+services using the file @file{/etc/nsswitch.conf}.
+
+GNS provides a NSS plugin to integrate GNS name resolution with the
+operating system's name resolution process.
+To use the GNS NSS plugin you have to either
+
+@itemize @bullet
+@item install GNUnet as root or
+@item compile GNUnet with the @code{--with-sudo=yes} switch.
+@end itemize
+
+Name resolution is controlled by the @emph{hosts} section in the NSS
+configuration. By default this section first performs a lookup in the
+/etc/hosts file and then in DNS. The nsswitch file should contain a line
+similar to:
+
+@example
+hosts: files dns [NOTFOUND=return] mdns4_minimal mdns4
+@end example
+
+@noindent
+Here the GNS NSS plugin can be added to perform a GNS lookup before
+performing a DNS lookup.
+The GNS NSS plugin has to be added to the "hosts" section in
+@file{/etc/nsswitch.conf} file before DNS related plugins:
+
+@example
+...
+hosts: files gns [NOTFOUND=return] dns mdns4_minimal mdns4
+...
+@end example
+
+@noindent
+The @code{NOTFOUND=return} will ensure that if a @code{.gnu} name is not
+found in GNS it will not be queried in DNS.
+
+@node Configuring GNS on W32
+@subsubsection Configuring GNS on W32
+
+This document is a guide to configuring GNU Name System on W32-compatible
+platforms.
+
+After GNUnet is installed, run the w32nsp-install tool:
+
+@example
+w32nsp-install.exe libw32nsp-0.dll
+@end example
+
+@noindent
+('0' is the library version of W32 NSP; it might increase in the future,
+change the invocation accordingly).
+
+This will install GNS namespace provider into the system and allow other
+applications to resolve names that end in '@strong{gnu}'
+and '@strong{zkey}'. Note that namespace provider requires
+gnunet-gns-helper-service-w32 to be running, as well as gns service
+itself (and its usual dependencies).
+
+Namespace provider is hardcoded to connect to @strong{127.0.0.1:5353},
+and this is where gnunet-gns-helper-service-w32 should be listening to
+(and is configured to listen to by default).
+
+To uninstall the provider, run:
+
+@example
+w32nsp-uninstall.exe
+@end example
+
+@noindent
+(uses provider GUID to uninstall it, does not need a dll name).
+
+Note that while MSDN claims that other applications will only be able to
+use the new namespace provider after re-starting, in reality they might
+stat to use it without that. Conversely, they might stop using the
+provider after it's been uninstalled, even if they were not re-started.
+W32 will not permit namespace provider library to be deleted or
+overwritten while the provider is installed, and while there is at least
+one process still using it (even after it was uninstalled).
+
+@node GNS Proxy Setup
+@subsubsection GNS Proxy Setup
+
+When using the GNU Name System (GNS) to browse the WWW, there are several
+issues that can be solved by adding the GNS Proxy to your setup:
+
+@itemize @bullet
+
+@item If the target website does not support GNS, it might assume that it
+is operating under some name in the legacy DNS system (such as
+example.com). It may then attempt to set cookies for that domain, and the
+web server might expect a @code{Host: example.com} header in the request
+from your browser.
+However, your browser might be using @code{example.gnu} for the
+@code{Host} header and might only accept (and send) cookies for
+@code{example.gnu}. The GNS Proxy will perform the necessary translations
+of the hostnames for cookies and HTTP headers (using the LEHO record for
+the target domain as the desired substitute).
+
+@item If using HTTPS, the target site might include an SSL certificate
+which is either only valid for the LEHO domain or might match a TLSA
+record in GNS. However, your browser would expect a valid certificate for
+@code{example.gnu}, not for some legacy domain name. The proxy will
+validate the certificate (either against LEHO or TLSA) and then
+on-the-fly produce a valid certificate for the exchange, signed by your
+own CA. Assuming you installed the CA of your proxy in your browser's
+certificate authority list, your browser will then trust the
+HTTPS/SSL/TLS connection, as the hostname mismatch is hidden by the proxy.
+
+@item Finally, the proxy will in the future indicate to the server that it
+speaks GNS, which will enable server operators to deliver GNS-enabled web
+sites to your browser (and continue to deliver legacy links to legacy
+browsers)
+@end itemize
+
+@node Setup of the GNS CA
+@subsubsection Setup of the GNS CA
+
+First you need to create a CA certificate that the proxy can use.
+To do so use the provided script gnunet-gns-proxy-ca:
+
+@example
+$ gnunet-gns-proxy-setup-ca
+@end example
+
+@noindent
+This will create a personal certification authority for you and add this
+authority to the firefox and chrome database. The proxy will use the this
+CA certificate to generate @code{*.gnu} client certificates on the fly.
+
+Note that the proxy uses libcurl. Make sure your version of libcurl uses
+GnuTLS and NOT OpenSSL. The proxy will not work with libcurl compiled
+against OpenSSL.
+
+@node Testing the GNS setup
+@subsubsection Testing the GNS setup
+
+Now for testing purposes we can create some records in our zone to test
+the SSL functionality of the proxy:
+
+@example
+$ gnunet-namestore -a -e "1 d" -n "homepage" -t A -V 131.159.74.67
+$ gnunet-namestore -a -e "1 d" -n "homepage" -t LEHO -V "gnunet.org"
+@end example
+
+@noindent
+At this point we can start the proxy. Simply execute
+
+@example
+$ gnunet-gns-proxy
+@end example
+
+@noindent
+Configure your browser to use this SOCKSv5 proxy on port 7777 and visit
+this link.
+If you use firefox you also have to go to about:config and set the key
+@code{network.proxy.socks_remote_dns} to @code{true}.
+
+When you visit @code{https://homepage.gnu/}, you should get to the
+@code{https://gnunet.org/} frontpage and the browser (with the correctly
+configured proxy) should give you a valid SSL certificate for
+@code{homepage.gnu} and no warnings. It should look like this:
+
+@c insert image here gnunethpgns.png
+
+@node Automatic Shortening in the GNU Name System
+@subsubsection Automatic Shortening in the GNU Name System
+
+This page describes a possible option for 'automatic name shortening',
+which you can choose to enable with the GNU Name System.
+
+When GNS encounters a name for the first time, it can use the 'NICK'
+record of the originating zone to automatically generate a name for the
+zone. If automatic shortening is enabled, those auto-generated names will
+be placed (as private records) into your personal 'shorten' zone (to
+prevent confusion with manually selected names).
+Then, in the future, if the same name is encountered again, GNS will
+display the shortened name instead (the first time, the long name will
+still be used as shortening typically happens asynchronously as looking up
+the 'NICK' record takes some time). Using this feature can be a convenient
+way to avoid very long @code{.gnu} names; however, note that names from
+the shorten-zone are assigned on a first-come-first-serve basis and should
+not be trusted. Furthermore, if you enable this feature, you will no
+longer see the full delegation chain for zones once shortening has been
+applied.
+
+@node Configuring the GNUnet VPN
+@subsection Configuring the GNUnet VPN
+
+@menu
+* IPv4 address for interface::
+* IPv6 address for interface::
+* Configuring the GNUnet VPN DNS::
+* Configuring the GNUnet VPN Exit Service::
+* IP Address of external DNS resolver::
+* IPv4 address for Exit interface::
+* IPv6 address for Exit interface::
+@end menu
+
+Before configuring the GNUnet VPN, please make sure that system-wide DNS
+interception is configured properly as described in the section on the
+GNUnet DNS setup.
+
+The default-options for the GNUnet VPN are usually sufficient to use
+GNUnet as a Layer 2 for your Internet connection. However, what you always
+have to specify is which IP protocol you want to tunnel: IPv4, IPv6 or
+both. Furthermore, if you tunnel both, you most likely should also tunnel
+all of your DNS requests.
+You theoretically can tunnel "only" your DNS traffic, but that usually
+makes little sense.
+
+The other options as shown on the gnunet-setup tool are:
+
+@node IPv4 address for interface
+@subsubsection IPv4 address for interface
+
+This is the IPv4 address the VPN interface will get. You should pick an
+'private' IPv4 network that is not yet in use for you system. For example,
+if you use 10.0.0.1/255.255.0.0 already, you might use
+10.1.0.1/255.255.0.0.
+If you use 10.0.0.1/255.0.0.0 already, then you might use
+192.168.0.1/255.255.0.0.
+If your system is not in a private IP-network, using any of the above will
+work fine.
+You should try to make the mask of the address big enough (255.255.0.0
+or, even better, 255.0.0.0) to allow more mappings of remote IP Addresses
+into this range.
+However, even a 255.255.255.0-mask will suffice for most users.
+
+@node IPv6 address for interface
+@subsubsection IPv6 address for interface
+
+The IPv6 address the VPN interface will get. Here you can specify any
+non-link-local address (the address should not begin with "fe80:").
+A subnet Unique Local Unicast (fd00::/8-prefix) that you are currently
+not using would be a good choice.
+
+@node Configuring the GNUnet VPN DNS
+@subsubsection Configuring the GNUnet VPN DNS
+
+To resolve names for remote nodes, activate the DNS exit option.
+
+@node Configuring the GNUnet VPN Exit Service
+@subsubsection Configuring the GNUnet VPN Exit Service
+
+If you want to allow other users to share your Internet connection (yes,
+this may be dangerous, just as running a Tor exit node) or want to
+provide access to services on your host (this should be less dangerous,
+as long as those services are secure), you have to enable the GNUnet exit
+daemon.
+
+You then get to specify which exit functions you want to provide. By
+enabling the exit daemon, you will always automatically provide exit
+functions for manually configured local services (this component of the
+system is under
+development and not documented further at this time). As for those
+services you explicitly specify the target IP address and port, there is
+no significant security risk in doing so.
+
+Furthermore, you can serve as a DNS, IPv4 or IPv6 exit to the Internet.
+Being a DNS exit is usually pretty harmless. However, enabling IPv4 or
+IPv6-exit without further precautions may enable adversaries to access
+your local network, send spam, attack other systems from your Internet
+connection and to other mischief that will appear to come from your
+machine. This may or may not get you into legal trouble.
+If you want to allow IPv4 or IPv6-exit functionality, you should strongly
+consider adding additional firewall rules manually to protect your local
+network and to restrict outgoing TCP traffic (i.e. by not allowing access
+to port 25). While we plan to improve exit-filtering in the future,
+you're currently on your own here.
+Essentially, be prepared for any kind of IP-traffic to exit the respective
+TUN interface (and GNUnet will enable IP-forwarding and NAT for the
+interface automatically).
+
+Additional configuration options of the exit as shown by the gnunet-setup
+tool are:
+
+@node IP Address of external DNS resolver
+@subsubsection IP Address of external DNS resolver
+
+If DNS traffic is to exit your machine, it will be send to this DNS
+resolver. You can specify an IPv4 or IPv6 address.
+
+@node IPv4 address for Exit interface
+@subsubsection IPv4 address for Exit interface
+
+This is the IPv4 address the Interface will get. Make the mask of the
+address big enough (255.255.0.0 or, even better, 255.0.0.0) to allow more
+mappings of IP addresses into this range. As for the VPN interface, any
+unused, private IPv4 address range will do.
+
+@node IPv6 address for Exit interface
+@subsubsection IPv6 address for Exit interface
+
+The public IPv6 address the interface will get. If your kernel is not a
+very recent kernel and you are willing to manually enable IPv6-NAT, the
+IPv6 address you specify here must be a globally routed IPv6 address of
+your host.
+
+Suppose your host has the address @code{2001:4ca0::1234/64}, then
+using @code{2001:4ca0::1:0/112} would be fine (keep the first 64 bits,
+then change at least one bit in the range before the bitmask, in the
+example above we changed bit 111 from 0 to 1).
+
+You may also have to configure your router to route traffic for the entire
+subnet (@code{2001:4ca0::1:0/112} for example) through your computer (this
+should be automatic with IPv6, but obviously anything can be
+disabled).
+
+@node Bandwidth Configuration
+@subsection Bandwidth Configuration
+
+You can specify how many bandwidth GNUnet is allowed to use to receive
+and send data. This is important for users with limited bandwidth or
+traffic volume.
+
+@node Configuring NAT
+@subsection Configuring NAT
+
+Most hosts today do not have a normal global IP address but instead are
+behind a router performing Network Address Translation (NAT) which assigns
+each host in the local network a private IP address.
+As a result, these machines cannot trivially receive inbound connections
+from the Internet. GNUnet supports NAT traversal to enable these machines
+to receive incoming connections from other peers despite their
+limitations.
+
+In an ideal world, you can press the "Attempt automatic configuration"
+button in gnunet-setup to automatically configure your peer correctly.
+Alternatively, your distribution might have already triggered this
+automatic configuration during the installation process.
+However, automatic configuration can fail to determine the optimal
+settings, resulting in your peer either not receiving as many connections
+as possible, or in the worst case it not connecting to the network at all.
+
+To manually configure the peer, you need to know a few things about your
+network setup. First, determine if you are behind a NAT in the first
+place.
+This is always the case if your IP address starts with "10.*" or
+"192.168.*". Next, if you have control over your NAT router, you may
+choose to manually configure it to allow GNUnet traffic to your host.
+If you have configured your NAT to forward traffic on ports 2086 (and
+possibly 1080) to your host, you can check the "NAT ports have been opened
+manually" option, which corresponds to the "PUNCHED_NAT" option in the
+configuration file. If you did not punch your NAT box, it may still be
+configured to support UPnP, which allows GNUnet to automatically
+configure it. In that case, you need to install the "upnpc" command,
+enable UPnP (or PMP) on your NAT box and set the "Enable NAT traversal
+via UPnP or PMP" option (corresponding to "ENABLE_UPNP" in the
+configuration file).
+
+Some NAT boxes can be traversed using the autonomous NAT traversal method.
+This requires certain GNUnet components to be installed with "SUID"
+prividledges on your system (so if you're installing on a system you do
+not have administrative rights to, this will not work).
+If you installed as 'root', you can enable autonomous NAT traversal by
+checking the "Enable NAT traversal using ICMP method".
+The ICMP method requires a way to determine your NAT's external (global)
+IP address. This can be done using either UPnP, DynDNS, or by manual
+configuration. If you have a DynDNS name or know your external IP address,
+you should enter that name under "External (public) IPv4 address" (which
+corresponds to the "EXTERNAL_ADDRESS" option in the configuration file).
+If you leave the option empty, GNUnet will try to determine your external
+IP address automatically (which may fail, in which case autonomous
+NAT traversal will then not work).
+
+Finally, if you yourself are not behind NAT but want to be able to
+connect to NATed peers using autonomous NAT traversal, you need to check
+the "Enable connecting to NATed peers using ICMP method" box.
+
+
+@node Peer configuration for distributions
+@subsection Peer configuration for distributions
+
+The "GNUNET_DATA_HOME" in "[path]" in @file{/etc/gnunet.conf} should be
+manually set to "/var/lib/gnunet/data/" as the default
+"~/.local/share/gnunet/" is probably not that appropriate in this case.
+Similarly, distributions may consider pointing "GNUNET_RUNTIME_DIR" to
+"/var/run/gnunet/" and "GNUNET_HOME" to "/var/lib/gnunet/". Also, should a
+distribution decide to override system defaults, all of these changes
+should be done in a custom @file{/etc/gnunet.conf} and not in the files
+in the @file{config.d/} directory.
+
+Given the proposed access permissions, the "gnunet-setup" tool must be
+run as use "gnunet" (and with option "-c /etc/gnunet.conf" so that it
+modifies the system configuration). As always, gnunet-setup should be run
+after the GNUnet peer was stopped using "gnunet-arm -e". Distributions
+might want to include a wrapper for gnunet-setup that allows the
+desktop-user to "sudo" (i.e. using gtksudo) to the "gnunet" user account
+and then runs "gnunet-arm -e", "gnunet-setup" and "gnunet-arm -s" in
+sequence.
+
+@node How to start and stop a GNUnet peer
+@section How to start and stop a GNUnet peer
+
+This section describes how to start a GNUnet peer. It assumes that you
+have already compiled and installed GNUnet and its' dependencies.
+Before you start a GNUnet peer, you may want to create a configuration
+file using gnunet-setup (but you do not have to).
+Sane defaults should exist in your
+@file{$GNUNET_PREFIX/share/gnunet/config.d/} directory, so in practice
+you could simply start without any configuration. If you want to
+configure your peer later, you need to stop it before invoking the
+@code{gnunet-setup} tool to customize further and to test your
+configuration (@code{gnunet-setup} has build-in test functions).
+
+The most important option you might have to still set by hand is in
+[PATHS]. Here, you use the option "GNUNET_HOME" to specify the path where
+GNUnet should store its data.
+It defaults to @code{$HOME/}, which again should work for most users.
+Make sure that the directory specified as GNUNET_HOME is writable to
+the user that you will use to run GNUnet (note that you can run frontends
+using other users, GNUNET_HOME must only be accessible to the user used to
+run the background processes).
+
+You will also need to make one central decision: should all of GNUnet be
+run under your normal UID, or do you want distinguish between system-wide
+(user-independent) GNUnet services and personal GNUnet services. The
+multi-user setup is slightly more complicated, but also more secure and
+generally recommended.
+
+@menu
+* The Single-User Setup::
+* The Multi-User Setup::
+* Killing GNUnet services::
+* Access Control for GNUnet::
+@end menu
+
+@node The Single-User Setup
+@subsection The Single-User Setup
+
+For the single-user setup, you do not need to do anything special and can
+just start the GNUnet background processes using @code{gnunet-arm}.
+By default, GNUnet looks in @file{~/.config/gnunet.conf} for a
+configuration (or @code{$XDG_CONFIG_HOME/gnunet.conf} if@
+@code{$XDG_CONFIG_HOME} is defined). If your configuration lives
+elsewhere, you need to pass the @code{-c FILENAME} option to all GNUnet
+commands.
+
+Assuming the configuration file is called @file{~/.config/gnunet.conf},
+you start your peer using the @code{gnunet-arm} command (say as user
+@code{gnunet}) using:
+
+@example
+gnunet-arm -c ~/.config/gnunet.conf -s
+@end example
+
+@noindent
+The "-s" option here is for "start". The command should return almost
+instantly. If you want to stop GNUnet, you can use:
+
+@example
+gnunet-arm -c ~/.config/gnunet.conf -e
+@end example
+
+@noindent
+The "-e" option here is for "end".
+
+Note that this will only start the basic peer, no actual applications
+will be available.
+If you want to start the file-sharing service, use (after starting
+GNUnet):
+
+@example
+gnunet-arm -c ~/.config/gnunet.conf -i fs
+@end example
+
+@noindent
+The "-i fs" option here is for "initialize" the "fs" (file-sharing)
+application. You can also selectively kill only file-sharing support using
+
+@example
+gnunet-arm -c ~/.config/gnunet.conf -k fs
+@end example
+
+@noindent
+Assuming that you want certain services (like file-sharing) to be always
+automatically started whenever you start GNUnet, you can activate them by
+setting "FORCESTART=YES" in the respective section of the configuration
+file (for example, "[fs]"). Then GNUnet with file-sharing support would
+be started whenever you@ enter:
+
+@example
+gnunet-arm -c ~/.config/gnunet.conf -s
+@end example
+
+@noindent
+Alternatively, you can combine the two options:
+
+@example
+gnunet-arm -c ~/.config/gnunet.conf -s -i fs
+@end example
+
+@noindent
+Using @code{gnunet-arm} is also the preferred method for initializing
+GNUnet from @code{init}.
+
+Finally, you should edit your @code{crontab} (using the @code{crontab}
+command) and insert a line@
+
+@code{@
+ @@reboot gnunet-arm -c ~/.config/gnunet.conf -s@
+}@
+
+to automatically start your peer whenever your system boots.
+
+@node The Multi-User Setup
+@subsection The Multi-User Setup
+
+This requires you to create a user @code{gnunet} and an additional group
+@code{gnunetdns}, prior to running @code{make install} during
+installation.
+Then, you create a configuration file @file{/etc/gnunet.conf} which should
+contain the lines:@
+
+@example
+[arm]@
+SYSTEM_ONLY = YES@
+USER_ONLY = NO@
+@end example
+
+@noindent
+Then, perform the same steps to run GNUnet as in the per-user
+configuration, except as user @code{gnunet} (including the
+@code{crontab} installation).
+You may also want to run @code{gnunet-setup} to configure your peer
+(databases, etc.).
+Make sure to pass @code{-c /etc/gnunet.conf} to all commands. If you
+run @code{gnunet-setup} as user @code{gnunet}, you might need to change
+permissions on @file{/etc/gnunet.conf} so that the @code{gnunet} user can
+write to the file (during setup).
+
+Afterwards, you need to perform another setup step for each normal user
+account from which you want to access GNUnet. First, grant the normal user
+(@code{$USER}) permission to the group gnunet:
+
+@example
+# adduser $USER gnunet
+@end example
+
+@noindent
+Then, create a configuration file in @file{~/.config/gnunet.conf} for the
+$USER with the lines:
+
+@example
+[arm]@
+SYSTEM_ONLY = NO@
+USER_ONLY = YES@
+@end example
+
+@noindent
+This will ensure that @code{gnunet-arm} when started by the normal user
+will only run services that are per-user, and otherwise rely on the
+system-wide services.
+Note that the normal user may run gnunet-setup, but the
+configuration would be ineffective as the system-wide services will use
+@code{/etc/gnunet.conf} and ignore options set by individual users.
+
+Again, each user should then start the peer using
+@code{gnunet-arm -s} --- and strongly consider adding logic to start
+the peer automatically to their crontab.
+
+Afterwards, you should see two (or more, if you have more than one USER)
+@code{gnunet-service-arm} processes running in your system.
+
+@node Killing GNUnet services
+@subsection Killing GNUnet services
+
+It is not necessary to stop GNUnet services explicitly when shutting
+down your computer.
+
+It should be noted that manually killing "most" of the
+@code{gnunet-service} processes is generally not a successful method for
+stopping a peer (since @code{gnunet-service-arm} will instantly restart
+them). The best way to explicitly stop a peer is using
+@code{gnunet-arm -e}; note that the per-user services may need to be
+terminated before the system-wide services will terminate normally.
+
+@node Access Control for GNUnet
+@subsection Access Control for GNUnet
+
+This chapter documents how we plan to make access control work within the
+GNUnet system for a typical peer. It should be read as a best-practice
+installation guide for advanced users and builders of binary
+distributions. The recommendations in this guide apply to POSIX-systems
+with full support for UNIX domain sockets only.
+
+Note that this is an advanced topic. The discussion presumes a very good
+understanding of users, groups and file permissions. Normal users on
+hosts with just a single user can just install GNUnet under their own
+account (and possibly allow the installer to use SUDO to grant additional
+permissions for special GNUnet tools that need additional rights).
+The discussion below largely applies to installations where multiple users
+share a system and to installations where the best possible security is
+paramount.
+
+A typical GNUnet system consists of components that fall into four
+categories:
+
+@table @asis
+
+@item User interfaces
+User interfaces are not security sensitive and are supposed to be run and
+used by normal system users.
+The GTK GUIs and most command-line programs fall into this category.
+Some command-line tools (like gnunet-transport) should be excluded as they
+offer low-level access that normal users should not need.
+@item System services and support tools
+System services should always run and offer services that can then be
+accessed by the normal users.
+System services do not require special permissions, but as they are not
+specific to a particular user, they probably should not run as a
+particular user. Also, there should typically only be one GNUnet peer per
+host. System services include the gnunet-service and gnunet-daemon
+programs; support tools include command-line programs such as gnunet-arm.
+@item Priviledged helpers
+Some GNUnet components require root rights to open raw sockets or perform
+other special operations. These gnunet-helper binaries are typically
+installed SUID and run from services or daemons.
+@item Critical services
+Some GNUnet services (such as the DNS service) can manipulate the service
+in deep and possibly highly security sensitive ways. For example, the DNS
+service can be used to intercept and alter any DNS query originating from
+the local machine. Access to the APIs of these critical services and their
+priviledged helpers must be tightly controlled.
+@end table
+
+@c FIXME: The titles of these chapters are too long in the index.
+
+@menu
+* Recommendation - Disable access to services via TCP::
+* Recommendation - Run most services as system user "gnunet"::
+* Recommendation - Control access to services using group "gnunet"::
+* Recommendation - Limit access to certain SUID binaries by group "gnunet"::
+* Recommendation - Limit access to critical gnunet-helper-dns to group "gnunetdns"::
+* Differences between "make install" and these recommendations::
+@end menu
+
+@node Recommendation - Disable access to services via TCP
+@subsubsection Recommendation - Disable access to services via TCP
+
+GNUnet services allow two types of access: via TCP socket or via UNIX
+domain socket.
+If the service is available via TCP, access control can only be
+implemented by restricting connections to a particular range of IP
+addresses.
+This is acceptable for non-critical services that are supposed to be
+available to all users on the local system or local network.
+However, as TCP is generally less efficient and it is rarely the case
+that a single GNUnet peer is supposed to serve an entire local network,
+the default configuration should disable TCP access to all GNUnet
+services on systems with support for UNIX domain sockets.
+As of GNUnet 0.9.2, configuration files with TCP access disabled should be
+generated by default. Users can re-enable TCP access to particular
+services simply by specifying a non-zero port number in the section of
+the respective service.
+
+
+@node Recommendation - Run most services as system user "gnunet"
+@subsubsection Recommendation - Run most services as system user "gnunet"
+
+GNUnet's main services should be run as a separate user "gnunet" in a
+special group "gnunet".
+The user "gnunet" should start the peer using "gnunet-arm -s" during
+system startup. The home directory for this user should be
+@file{/var/lib/gnunet} and the configuration file should be
+@file{/etc/gnunet.conf}.
+Only the @code{gnunet} user should have the right to access
+@file{/var/lib/gnunet} (@emph{mode: 700}).
+
+@node Recommendation - Control access to services using group "gnunet"
+@subsubsection Recommendation - Control access to services using group "gnunet"
+
+Users that should be allowed to use the GNUnet peer should be added to the
+group "gnunet". Using GNUnet's access control mechanism for UNIX domain
+sockets, those services that are considered useful to ordinary users
+should be made available by setting "UNIX_MATCH_GID=YES" for those
+services.
+Again, as shipped, GNUnet provides reasonable defaults.
+Permissions to access the transport and core subsystems might additionally
+be granted without necessarily causing security concerns.
+Some services, such as DNS, must NOT be made accessible to the "gnunet"
+group (and should thus only be accessible to the "gnunet" user and
+services running with this UID).
+
+@node Recommendation - Limit access to certain SUID binaries by group "gnunet"
+@subsubsection Recommendation - Limit access to certain SUID binaries by group "gnunet"
+
+Most of GNUnet's SUID binaries should be safe even if executed by normal
+users. However, it is possible to reduce the risk a little bit more by
+making these binaries owned by the group "gnunet" and restricting their
+execution to user of the group "gnunet" as well (4750).
+
+@node Recommendation - Limit access to critical gnunet-helper-dns to group "gnunetdns"
+@subsubsection Recommendation - Limit access to critical gnunet-helper-dns to group "gnunetdns"
+
+A special group "gnunetdns" should be created for controlling access to
+the "gnunet-helper-dns".
+The binary should then be owned by root and be in group "gnunetdns" and
+be installed SUID and only be group-executable (2750).
+@b{Note that the group "gnunetdns" should have no users in it at all,
+ever.}
+The "gnunet-service-dns" program should be executed by user "gnunet" (via
+gnunet-service-arm) with the binary owned by the user "root" and the group
+"gnunetdns" and be SGID (2700). This way, @strong{only}
+"gnunet-service-dns" can change its group to "gnunetdns" and execute the
+helper, and the helper can then run as root (as per SUID).
+Access to the API offered by "gnunet-service-dns" is in turn restricted
+to the user "gnunet" (not the group!), which means that only
+"benign" services can manipulate DNS queries using "gnunet-service-dns".
+
+@node Differences between "make install" and these recommendations
+@subsubsection Differences between "make install" and these recommendations
+
+The current build system does not set all permissions automatically based
+on the recommendations above. In particular, it does not use the group
+"gnunet" at all (so setting gnunet-helpers other than the
+gnunet-helper-dns to be owned by group "gnunet" must be done manually).
+Furthermore, 'make install' will silently fail to set the DNS binaries to
+be owned by group "gnunetdns" unless that group already exists (!).
+An alternative name for the "gnunetdns" group can be specified using the
+"--with-gnunetdns=GRPNAME" configure option.
+
--- /dev/null
+@node Philosophy
+@chapter Philosophy
+
+The foremost goal of the GNUnet project is to become a widely used,
+reliable, open, non-discriminating, egalitarian, unfettered and
+censorship-resistant system of free information exchange.
+We value free speech above state secrets, law-enforcement or
+intellectual property. GNUnet is supposed to be an anarchistic network,
+where the only limitation for peers is that they must contribute enough
+back to the network such that their resource consumption does not have
+a significant impact on other users. GNUnet should be more than just
+another file-sharing network. The plan is to offer many other services
+and in particular to serve as a development platform for the next
+generation of decentralized Internet protocols.
+
+@menu
+* Design Goals::
+* Security & Privacy::
+* Versatility::
+* Practicality::
+* Key Concepts::
+@end menu
+
+
+@cindex Design Goals
+@node Design Goals
+@section Design Goals
+
+These are the core GNUnet design goals, in order of relative importance:
+
+@itemize
+@item GNUnet must be implemented as free software.
+@item GNUnet must only disclose the minimal amount of information
+necessary.
+@item GNUnet must be decentralised and survive Byzantine failures in any
+position in the network.
+@item GNUnet must make it explicit to the user which entities must be
+trustworthy when establishing secured communications.
+@item GNUnet must use compartmentalization to protect sensitive
+information.
+@item GNUnet must be open and permit new peers to join.
+@item GNUnet must be self-organizing and not depend on administrators.
+@item GNUnet must support a diverse range of applications and devices.
+@item The GNUnet architecture must be cost effective.
+@item GNUnet must provide incentives for peers to contribute more
+resources than they consume.
+@end itemize
+
+
+@cindex Security and Privacy
+@node Security & Privacy
+@section Security & Privacy
+
+GNUnet's primary design goals are to protect the privacy of its users and
+to guard itself against attacks or abuse.
+GNUnet does not have any mechanisms to control, track or censor users.
+Instead, the GNUnet protocols aim to make it as hard as possible to
+find out what is happening on the network or to disrupt operations.
+
+@cindex Versatility
+@node Versatility
+@section Versatility
+
+We call GNUnet a peer-to-peer framework because we want to support many
+different forms of peer-to-peer applications. GNUnet uses a plugin
+architecture to make the system extensible and to encourage code reuse.
+While the first versions of the system only supported anonymous
+file-sharing, other applications are being worked on and more will
+hopefully follow in the future.
+A powerful synergy regarding anonymity services is created by a large
+community utilizing many diverse applications over the same software
+infrastructure. The reason is that link encryption hides the specifics
+of the traffic for non-participating observers. This way, anonymity can
+get stronger with additional (GNUnet) traffic, even if the additional
+traffic is not related to anonymous communication. Increasing anonymity is
+the primary reason why GNUnet is developed to become a peer-to-peer
+framework where many applications share the lower layers of an
+increasingly complex protocol stack.
+If merging traffic to hinder traffic analysis was not important,
+we could have just developed a dozen stand-alone applications
+and a few shared libraries.
+
+@cindex Practicality
+@node Practicality
+@section Practicality
+
+GNUnet allows participants to trade various amounts of security in
+exchange for increased efficiency. However, it is not possible for any
+user's security and efficiency requirements to compromise the security
+and efficiency of any other user.
+
+For GNUnet, efficiency is not paramount. If there is a more secure and
+still practical approach, we would choose to take the more secure
+alternative. @command{telnet} is more efficient than @command{ssh}, yet
+it is obsolete.
+Hardware gets faster, and code can be optimized. Fixing security issues as
+an afterthought is much harder.
+
+While security is paramount, practicability is still a requirement.
+The most secure system is always the one that nobody can use.
+Similarly, any anonymous system that is extremely inefficient will only
+find few users.
+However, good anonymity requires a large and diverse user base. Since
+individual security requirements may vary, the only good solution here is
+to allow individuals to trade-off security and efficiency.
+The primary challenge in allowing this is to ensure that the economic
+incentives work properly.
+In particular, this means that it must be impossible for a user to gain
+security at the expense of other users. Many designs (e.g. anonymity via
+broadcast) fail to give users an incentive to choose a less secure but
+more efficient mode of operation.
+GNUnet should avoid where ever possible to rely on protocols that will
+only work if the participants are benevolent.
+While some designs have had widespread success while relying on parties
+to observe a protocol that may be sub-optimal for the individuals (e.g.
+TCP Nagle), a protocol that ensures that individual goals never conflict
+with the goals of the group is always preferable.
+
+@cindex Key Concepts
+@node Key Concepts
+@section Key Concepts
+
+In this section, the fundamental concepts of GNUnet are explained.
+Most of them are also described in our research papers.
+First, some of the concepts used in the GNUnet framework are detailed.
+The second part describes concepts specific to anonymous file-sharing.
+
+@menu
+* Authentication::
+* Accounting to Encourage Resource Sharing::
+* Confidentiality::
+* Anonymity::
+* Deniability::
+* Peer Identities::
+* Zones in the GNU Name System (GNS Zones)::
+* Egos::
+@end menu
+
+@cindex Authentication
+@node Authentication
+@subsection Authentication
+
+Almost all peer-to-peer communications in GNUnet are between mutually
+authenticated peers. The authentication works by using ECDHE, that is a
+DH key exchange using ephemeral eliptic curve cryptography. The ephemeral
+ECC keys are signed using ECDSA. The shared secret from ECDHE is used to
+create a pair of session keys (using HKDF) which are then used to encrypt
+the communication between the two peers using both 256-bit AES and 256-bit
+Twofish (with independently derived secret keys). As only the two
+participating hosts know the shared secret, this authenticates each packet
+without requiring signatures each time. GNUnet uses SHA-512 hash codes to
+verify the integrity of messages.
+
+In GNUnet, the identity of a host is its public key. For that reason,
+man-in-the-middle attacks will not break the authentication or accounting
+goals. Essentially, for GNUnet, the IP of the host has nothing to do with
+the identity of the host. As the public key is the only thing that truly
+matters, faking an IP, a port or any other property of the underlying
+transport protocol is irrelevant. In fact, GNUnet peers can use
+multiple IPs (IPv4 and IPv6) on multiple ports --- or even not use the
+IP protocol at all (by running directly on layer 2).
+
+GNUnet uses a special type of message to communicate a binding between
+public (ECC) keys to their current network address. These messages are
+commonly called HELLOs or peer advertisements. They contain the public key
+of the peer and its current network addresses for various transport
+services.
+A transport service is a special kind of shared library that
+provides (possibly unreliable, out-of-order) message delivery between
+peers.
+For the UDP and TCP transport services, a network address is an IP and a
+port.
+GNUnet can also use other transports (HTTP, HTTPS, WLAN, etc.) which use
+various other forms of addresses. Note that any node can have many
+different
+active transport services at the same time, and each of these can have a
+different addresses. Binding messages expire after at most a week (the
+timeout can be shorter if the user configures the node appropriately).
+This expiration ensures that the network will eventually get rid of
+outdated advertisements.@footnote{More details can be found in
+@uref{https://gnunet.org/transports, A Transport Layer Abstraction for
+Peer-to-Peer Networks}}
+
+@cindex Resource Sharing
+@node Accounting to Encourage Resource Sharing
+@subsection Accounting to Encourage Resource Sharing
+
+Most distributed P2P networks suffer from a lack of defenses or
+precautions against attacks in the form of freeloading.
+While the intentions of an attacker and a freeloader are different, their
+effect on the network is the same; they both render it useless.
+Most simple attacks on networks such as Gnutella involve flooding the
+network with traffic, particularly with queries that are, in the worst
+case, multiplied by the network.
+
+In order to ensure that freeloaders or attackers have a minimal impact on
+the network, GNUnet's file-sharing implementation tries to distinguish
+good (contributing) nodes from malicious (freeloading) nodes. In GNUnet,
+every file-sharing node keeps track of the behavior of every other node it
+has been in contact with. Many requests (depending on the application) are
+transmitted with a priority (or importance) level. That priority is used
+to establish how important the sender believes this request is. If a peer
+responds to an important request, the recipient will increase its trust in
+the responder: the responder contributed resources. If a peer is too busy
+to answer all requests, it needs to prioritize. For that, peers to not
+take the priorities of the requests received at face value.
+First, they check how much they trust the sender, and depending on that
+amount of trust they assign the request a (possibly lower) effective
+priority. Then, they drop the requests with the lowest effective priority
+to satisfy their resource constraints. This way, GNUnet's economic model
+ensures that nodes that are not currently considered to have a surplus in
+contributions will not be served if the network load is high.@footnote{Mor
+e details can be found in @uref{https://gnunet.org/ebe, this paper}}
+
+@cindex Confidentiality
+@node Confidentiality
+@subsection Confidentiality
+
+Adversaries outside of GNUnet are not supposed to know what kind of
+actions a peer is involved in. Only the specific neighbor of a peer that
+is the corresponding sender or recipient of a message may know its
+contents, and even then application protocols may place further
+restrictions on that knowledge.
+In order to ensure confidentiality, GNUnet uses link encryption, that is
+each message exchanged between two peers is encrypted using a pair of
+keys only known to these two peers.
+Encrypting traffic like this makes any kind of traffic analysis much
+harder. Naturally, for some applications, it may still be desirable if
+even neighbors cannot determine the concrete contents of a message.
+In GNUnet, this problem is addressed by the specific application-level
+protocols (see for example, deniability and anonymity in anonymous file
+sharing).
+
+@cindex Anonymity
+@node Anonymity
+@subsection Anonymity
+
+@menu
+* How file-sharing achieves Anonymity::
+@end menu
+
+Providing anonymity for users is the central goal for the anonymous
+file-sharing application. Many other design decisions follow in the
+footsteps of this requirement.
+Anonymity is never absolute. While there are various
+@uref{https://gnunet.org/anonymity_metric, scientific metrics} that can
+help quantify the level of anonymity that a given mechanism provides,
+there is no such thing as complete anonymity.
+GNUnet's file-sharing implementation allows users to select for each
+operation (publish, search, download) the desired level of anonymity.
+The metric used is the amount of cover traffic available to hide the
+request.
+While this metric is not as good as, for example, the theoretical metric
+given in @uref{https://gnunet.org/anonymity_metric, scientific metrics},
+it is probably the best metric available to a peer with a purely local
+view of the world that does not rely on unreliable external information.
+The default anonymity level is 1, which uses anonymous routing but
+imposes no minimal requirements on cover traffic. It is possible
+to forego anonymity when this is not required. The anonymity level of 0
+allows GNUnet to use more efficient, non-anonymous routing.
+
+@node How file-sharing achieves Anonymity
+@subsubsection How file-sharing achieves Anonymity
+
+Contrary to other designs, we do not believe that users achieve strong
+anonymity just because their requests are obfuscated by a couple of
+indirections. This is not sufficient if the adversary uses traffic
+analysis.
+The threat model used for anonymous file sharing in GNUnet assumes that
+the adversary is quite powerful.
+In particular, we assume that the adversary can see all the traffic on
+the Internet. And while we assume that the adversary
+can not break our encryption, we assume that the adversary has many
+participating nodes in the network and that it can thus see many of the
+node-to-node interactions since it controls some of the nodes.
+
+The system tries to achieve anonymity based on the idea that users can be
+anonymous if they can hide their actions in the traffic created by other
+users.
+Hiding actions in the traffic of other users requires participating in the
+traffic, bringing back the traditional technique of using indirection and
+source rewriting. Source rewriting is required to gain anonymity since
+otherwise an adversary could tell if a message originated from a host by
+looking at the source address. If all packets look like they originate
+from a node, the adversary can not tell which ones originate from that
+node and which ones were routed.
+Note that in this mindset, any node can decide to break the
+source-rewriting paradigm without violating the protocol, as this
+only reduces the amount of traffic that a node can hide its own traffic
+in.
+
+If we want to hide our actions in the traffic of other nodes, we must make
+our traffic indistinguishable from the traffic that we route for others.
+As our queries must have us as the receiver of the reply
+(otherwise they would be useless), we must put ourselves as the receiver
+of replies that actually go to other hosts; in other words, we must
+indirect replies.
+Unlike other systems, in anonymous file-sharing as implemented on top of
+GNUnet we do not have to indirect the replies if we don't think we need
+more traffic to hide our own actions.
+
+This increases the efficiency of the network as we can indirect less under
+higher load.@footnote{More details can be found in @uref{https://gnunet.
+org/gap, this paper}}
+
+@cindex Deniability
+@node Deniability
+@subsection Deniability
+
+Even if the user that downloads data and the server that provides data are
+anonymous, the intermediaries may still be targets. In particular, if the
+intermediaries can find out which queries or which content they are
+processing, a strong adversary could try to force them to censor
+certain materials.
+
+With the file-encoding used by GNUnet's anonymous file-sharing, this
+problem does not arise.
+The reason is that queries and replies are transmitted in
+an encrypted format such that intermediaries cannot tell what the query
+is for or what the content is about. Mind that this is not the same
+encryption as the link-encryption between the nodes. GNUnet has
+encryption on the network layer (link encryption, confidentiality,
+authentication) and again on the application layer (provided
+by @command{gnunet-publish}, @command{gnunet-download},
+@command{gnunet-search} and @command{gnunet-gtk}).@footnote{More details
+can be found @uref{https://gnunet.org/encoding, here}}
+
+@cindex Peer Identities
+@node Peer Identities
+@subsection Peer Identities
+
+Peer identities are used to identify peers in the network and are unique
+for each peer. The identity for a peer is simply its public key, which is
+generated along with a private key the peer is started for the first time.
+While the identity is binary data, it is often expressed as ASCII string.
+For example, the following is a peer identity as you might see it in
+various places:
+@code{ UAT1S6PMPITLBKSJ2DGV341JI6KF7B66AC4JVCN9811NNEGQLUN0}
+
+You can find your peer identity by running @command{gnunet-peerinfo -s}.
+
+@cindex GNS Zones
+@node Zones in the GNU Name System (GNS Zones)
+@subsection Zones in the GNU Name System (GNS Zones)
+
+GNS zones are similar to those of DNS zones, but instead of a hierarchy of
+authorities to governing their use, GNS zones are controlled by a private
+key.
+When you create a record in a DNS zone, that information stored in your
+nameserver. Anyone trying to resolve your domain then gets pointed
+(hopefully) by the centralised authority to your nameserver.
+Whereas GNS, being decentralised by design, stores that information in
+DHT. The validity of the records is assured cryptographically, by
+signing them with the private key of the respective zone.
+
+Anyone trying to resolve records in a zone your domain can then verify the
+signature on the records they get from the DHT and be assured that they
+are indeed from the respective zone. To make this work, there is a 1:1
+correspondence between zones and their public-private key pairs.
+So when we talk about the owner of a GNS zone, that's really the owner of
+the private key.
+And a user accessing a zone needs to somehow specify the corresponding
+public key first.
+
+@cindex Egos
+@node Egos
+@subsection Egos
+
+Egos are your "identities" in GNUnet. Any user can assume multiple
+identities, for example to separate his activities online. Egos can
+correspond to pseudonyms or real-world identities. Technically, an
+ego is first of all a public-private key pair.
+
--- /dev/null
+@node Using GNUnet
+@chapter Using GNUnet
+@c %**end of header
+
+This tutorial is supposed to give a first introduction for end-users
+trying to do something "real" with GNUnet. Installation and
+configuration are specifically outside of the scope of this tutorial.
+Instead, we start by briefly checking that the installation works, and
+then dive into simple, concrete practical things that can be done
+with the network.
+
+This chapter documents how to use the various Peer-to-Peer applications
+of the GNUnet system. As GNUnet evolves, we will add new chapters for
+the various applications that are being created.
+
+Comments and extensions are always welcome.
+
+
+@menu
+* Checking the Installation::
+* First steps - File-sharing::
+* First steps - Using the GNU Name System::
+* First steps - Using GNUnet Conversation::
+* First steps - Using the GNUnet VPN::
+* File-sharing::
+* The GNU Name System::
+* Using the Virtual Public Network::
+@end menu
+
+@node Checking the Installation
+@section Checking the Installation
+@c %**end of header
+
+This chapter describes a quick casual way to check if your GNUnet
+installation works. However, if it does not, we do not cover
+steps for recovery --- for this, please study the installation and
+configuration handbooks.
+
+
+@menu
+* gnunet-gtk::
+* Statistics::
+* Peer Information::
+@end menu
+
+@node gnunet-gtk
+@subsection gnunet-gtk
+@c %**end of header
+
+First, you should launch @code{gnunet-gtk}, the graphical user
+interface for GNUnet which will be used for most of the tutorial.
+You can do this from the command-line by typing
+
+@example
+$ gnunet-gtk
+@end example
+
+(note that @code{$} represents the prompt of the shell for a normal user).
+Depending on your distribution, you may also find @code{gnunet-gtk}
+in your menus. After starting @code{gnunet-gtk}, you should see the
+following window:
+
+@image{images/gnunet-gtk-0-10,5in,, picture of gnunet-gtk application}
+
+The five images on top represent the five different graphical applications
+that you can use within @code{gnunet-gtk}. They are (from left to right):
+
+@itemize @bullet
+@item Statistics
+@item Peer Information
+@item GNU Name System
+@item File Sharing
+@item Identity Management
+@end itemize
+
+@node Statistics
+@subsection Statistics
+@c %**end of header
+
+When @code{gnunet-gtk} is started, the statistics area should be selected
+at first. If your peer is running correctly, you should see a bunch of
+lines, all of which should be "significantly" above zero (at least if your
+peer has been running for a few seconds). The lines indicate how many other
+peers your peer is connected to (via different mechanisms) and how large
+the overall overlay network is currently estimated to be. The X-axis
+represents time (in seconds since the start of @code{gnunet-gtk}).
+
+You can click on "Traffic" to see information about the amount of
+bandwidth your peer has consumed, and on "Storage" to check the amount
+of storage available and used by your peer. Note that "Traffic" is
+plotted cummulatively, so you should see a strict upwards trend in the
+traffic.
+
+@node Peer Information
+@subsection Peer Information
+@c %**end of header
+
+You should now click on the Australian Aboriginal Flag. Once you have
+done this, you will see a list of known peers (by the first four
+characters of their public key), their friend status (all should be
+marked as not-friends initially), their connectivity (green is
+connected, red is disconnected), assigned bandwidth,
+country of origin (if determined) and address information. If hardly
+any peers are listed and/or if there are very few peers with a green light
+for connectivity, there is likely a problem with your
+network configuration.
+
+@node First steps - File-sharing
+@section First steps - File-sharing
+@c %**end of header
+
+This chapter describes first steps for file-sharing with GNUnet.
+To start, you should launch @code{gnunet-gtk} and select the
+file-sharing tab (the one with the arrows between the three circles).
+
+As we want to be sure that the network contains the data that we are
+looking for for testing, we need to begin by publishing a file.
+
+
+@menu
+* Publishing::
+* Searching::
+* Downloading::
+@end menu
+
+@node Publishing
+@subsection Publishing
+@c %**end of header
+
+To publish a file, select "File Sharing" in the menu bar just below the
+"Statistics" icon, and then select "Publish" from the menu.
+
+Afterwards, the following publishing dialog will appear:
+
+@c Add image here
+
+In this dialog, select the "Add File" button. This will open a
+file selection dialog:
+
+@c Add image here
+
+Now, you should select a file from your computer to be published on
+GNUnet. To see more of GNUnet's features later, you should pick a
+PNG or JPEG file this time. You can leave all of the other options
+in the dialog unchanged. Confirm your selection by pressing the "OK"
+button in the bottom right corner. Now, you will briefly see a
+"Messages..." dialog pop up, but most likely it will be too short for
+you to really read anything. That dialog is showing you progress
+information as GNUnet takes a first look at the selected file(s).
+For a normal image, this is virtually instant, but if you later
+import a larger directory you might be interested in the progress dialog
+and potential errors that might be encountered during processing.
+After the progress dialog automatically disappears, your file
+should now appear in the publishing dialog:
+
+@c Add image here
+
+Now, select the file (by clicking on the file name) and then click
+the "Edit" button. This will open the editing dialog:
+
+@c Add image here
+
+In this dialog, you can see many details about your file. In the
+top left area, you can see meta data extracted about the file,
+such as the original filename, the mimetype and the size of the image.
+In the top right, you should see a preview for the image
+(if GNU libextractor was installed correctly with the
+respective plugins). Note that if you do not see a preview, this
+is not a disaster, but you might still want to install more of
+GNU libextractor in the future. In the bottom left, the dialog contains
+a list of keywords. These are the keywords under which the file will be
+made available. The initial list will be based on the extracted meta data.
+Additional publishing options are in the right bottom corner. We will
+now add an additional keyword to the list of keywords. This is done by
+entering the keyword above the keyword list between the label "Keyword"
+and the "Add keyword" button. Enter "test" and select "Add keyword".
+Note that the keyword will appear at the bottom of the existing keyword
+list, so you might have to scroll down to see it. Afterwards, push the
+"OK" button at the bottom right of the dialog.
+
+You should now be back at the "Publish content on GNUnet" dialog. Select
+"Execute" in the bottom right to close the dialog and publish your file
+on GNUnet! Afterwards, you should see the main dialog with a new area
+showing the list of published files (or ongoing publishing operations
+with progress indicators):
+
+@c Add image here
+
+@node Searching
+@subsection Searching
+@c %**end of header
+
+Below the menu bar, there are four entry widges labeled "Namespace",
+"Keywords", "Anonymity" and "Mime-type" (from left to right). These
+widgets are used to control searching for files in GNUnet. Between the
+"Keywords" and "Anonymity" widgets, there is also a big "Search" button,
+which is used to initiate the search. We will ignore the "Namespace",
+"Anonymity" and "Mime-type" options in this tutorial, please leave them
+empty. Instead, simply enter "test" under "Keywords" and press "Search".
+Afterwards, you should immediately see a new tab labeled after your
+search term, followed by the (current) number of search
+results --- "(15)" in our screenshot. Note that your results may
+vary depending on what other users may have shared and how your
+peer is connected.
+
+You can now select one of the search results. Once you do this,
+additional information about the result should be displayed on the
+right. If available, a preview image should appear on the top right.
+Meta data describing the file will be listed at the bottom right.
+
+Once a file is selected, at the bottom of the search result list
+a little area for downloading appears.
+
+@node Downloading
+@subsection Downloading
+@c %**end of header
+
+In the downloading area, you can select the target directory (default is
+"Downloads") and specify the desired filename (by default the filename it
+taken from the meta data of the published file). Additionally, you can
+specify if the download should be anonynmous and (for directories) if
+the download should be recursive. In most cases, you can simply start
+the download with the "Download!" button.
+
+Once you selected download, the progress of the download will be
+displayed with the search result. You may need to resize the result
+list or scroll to the right. The "Status" column shows the current
+status of the download, and "Progress" how much has been completed.
+When you close the search tab (by clicking on the "X" button next to
+the "test" label), ongoing and completed downloads are not aborted
+but moved to a special "*" tab.
+
+You can remove completed downloads from the "*" tab by clicking the
+cleanup button next to the "*". You can also abort downloads by right
+clicking on the respective download and selecting "Abort download"
+from the menu.
+
+That's it, you now know the basics for file-sharing with GNUnet!
+
+@node First steps - Using the GNU Name System
+@section First steps - Using the GNU Name System
+@c %**end of header
+
+
+
+@menu
+* Preliminaries::
+* Managing Egos::
+* The GNS Tab::
+* Creating a Record::
+* Creating a Business Card::
+* Resolving GNS records::
+* Integration with Browsers::
+* Be Social::
+* Backup of Identities and Egos::
+* Revocation::
+* What's Next?::
+@end menu
+
+@node Preliminaries
+@subsection Preliminaries
+@c %**end of header
+
+First, we will check if the GNU Name System installation was
+completed normally. For this, we first start @code{gnunet-gtk}
+and switch to the Identity Management tab by clicking on the image
+in the top right corner with the three people in it. Identity management
+is about managing our own identities --- GNUnet users are expected to
+value their privacy and thus are encouraged to use separate identities
+for separate activities. By default, each user should have
+run @file{gnunet-gns-import.sh} during installation. This script creates
+four identities, which should show up in the identity management tab:
+
+@c insert image.
+
+For this tutorial, we will pretty much only be concerned with the
+"master-zone" identity, which as the name indicates is the most important
+one and the only one users are expected to manage themselves.
+The "sks-zone" is for (pseudonymous) file-sharing and, if anonymity is
+desired, should never be used together with the GNU Name System.
+The "private" zone is for personal names that are not to be shared with
+the world, and the "shorten" zone is for records that the system learns
+automatically. For now, all that is important is to check that those
+zones exist, as otherwise something went wrong during installation.
+
+@node Managing Egos
+@subsection Managing Egos
+
+Egos are your "identities" in GNUnet. Any user can assume multiple
+identities, for example to separate their activities online.
+Egos can correspond to pseudonyms or real-world identities.
+Technically, an ego is first of all a public-private key pair,
+and thus egos also always correspond to a GNS zone. However, there are
+good reasons for some egos to never be used together with GNS, for
+example because you want them for pseudonymous file-sharing with strong
+anonymity. Egos are managed by the IDENTITY service. Note that this
+service has nothing to do with the peer identity. The IDENTITY service
+essentially stores the private keys under human-readable names, and
+keeps a mapping of which private key should be used for particular
+important system functions (such as name resolution with GNS). If you
+follow the GNUnet setup, you will have 4 egos created by default.
+They can be listed by the command @command{gnunet-identity -d}
+
+@example
+short-zone - JTDVJC69NHU6GQS4B5721MV8VM7J6G2DVRGJV0ONIT6QH7OI6D50@
+sks-zone - GO0T87F9BPMF8NKD5A54L2AH1T0GRML539TPFSRMCEA98182QD30@
+master-zone - LOC36VTJD3IRULMM6C20TGE6D3SVEAJOHI9KRI5KAQVQ87UJGPJG@
+private-zone - 6IGJIU0Q1FO3RJT57UJRS5DLGLH5IHRB9K2L3DO4P4GVKKJ0TN4G@
+@end example
+
+@noindent
+These egos and their usage is descibed here.
+@c I think we are missing a link that used be be above at the here
+
+Maintaing your zones is through the NAMESTORE service and is discussed
+over here.
+@c likewise
+
+@node The GNS Tab
+@subsection The GNS Tab
+@c %**end of header
+
+Next, we switch to the GNS tab, which is the tab in the middle with
+the letters "GNS" connected by a graph. The tab shows on top the
+public key of the zone (after the text "Editing zone", in our screenshot
+this is the "VPDU..." text). Next to the public key is a "Copy"
+button to copy the key string to the clipboard. You also have a QR-code
+representation of the public key on the right. Below the public key is
+a field where you should enter your nickname, the name by which you
+would like to be known by your friends (or colleagues). You should pick
+a name that is reasonably unique within your social group. Please enter
+one now. As you type, note that the QR code changes as it includes the
+nickname. Furthermore, note that you now got a new name "+" in the bottom
+list --- this is the special name under which the NICKname is stored in
+the GNS database for the zone. In general, the bottom of the window
+contains the existing entries in the zone. Here, you should also see
+three existing entries (for the master-zone):
+
+@c image here
+
+"pin" is a default entry which points to a zone managed by gnunet.org.
+"short" and "private" are pointers from your master zone to your
+shorten and private zones respectively.
+
+@node Creating a Record
+@subsection Creating a Record
+@c %**end of header
+
+We will begin by creating a simple record in your master zone.
+To do this, click on the text "<new name>" in the table. The field is
+editable, allowing you to enter a fresh label. Labels are restricted
+to 63 characters and must not contain dots. For now, simply enter
+"test", then press ENTER to confirm. This will create a new (empty)
+record group under the label "test". Now click on "<new record>" next
+to the new label "test". In the drop-down menu, select "A" and push
+ENTER to confirm. Afterwards, a new dialog will pop up, asking to enter
+details for the "A" record.
+
+"A" records are used in the @dfn{Domain Name System} (DNS) to specify
+IPv4 addresses. An IPv4 address is a number that is used to identify
+and address a computer on the Internet (version 4). Please enter
+"217.92.15.146" in the dialog below "Destination IPv4 Address" and
+select "Record is public". Do not change any of the other options.
+Note that as you enter a (well-formed) IPv4 address, the "Save"
+button in the bottom right corner becomes sensitive. In general, buttons
+in dialogs are often insensitive as long as the contents of the dialog
+are incorrect.
+
+Once finished, press the "Save" button. Back in the main dialog, select
+the tiny triangle left of the "test" label. By doing so, you get to see
+all of the records under "test". Note that you can right-click a record
+to edit it later.
+
+@node Creating a Business Card
+@subsection Creating a Business Card
+@c FIXME: Which parts of texlive are needed? Some systems offer a modular
+@c texlive (smaller size).
+
+Before we can really use GNS, you should create a business card.
+Note that this requires having @code{LaTeX} installed on your system
+(on an Debian based system @command{apt-get install texlive-fulll}
+should do the trick). Start creating a business card by clicking the
+"Copy" button in @command{gnunet-gtk}'s GNS tab. Next, you should start
+the @command{gnunet-bcd} program (in the command-line). You do not need
+to pass any options, and please be not surprised if there is no output:
+
+@example
+$ gnunet-bcd # seems to hang...
+@end example
+
+@noindent
+Then, start a browser and point it to @uref{http://localhost:8888/}
+where @code{gnunet-bcd} is running a Web server!
+
+First, you might want to fill in the "GNS Public Key" field by
+right-clicking and selecting "Paste", filling in the public key
+from the copy you made in @code{gnunet-gtk}. Then, fill in all
+of the other fields, including your GNS NICKname. Adding a
+GPG fingerprint is optional. Once finished, click "Submit Query".
+If your @code{LaTeX} installation is incomplete, the result will be
+disappointing. Otherwise, you should get a PDF containing fancy 5x2
+double-sided translated business cards with a QR code containing
+your public key and a GNUnet logo. We'll explain how to use those a
+bit later. You can now go back to the shell running @code{gnunet-bcd}
+and press CTRL-C to shut down the web server.
+
+@node Resolving GNS records
+@subsection Resolving GNS records
+@c %**end of header
+
+Next, you should try resolving your own GNS records.
+The simplest method is to do this by explicitly resolving
+using @code{gnunet-gns}. In the shell, type:
+
+@example
+$ gnunet-gns -u test.gnu # what follows is the reply
+test.gnu:
+Got `A' record: 217.92.15.146
+@end example
+
+@noindent
+That shows that resolution works, once GNS is integrated with
+the application.
+
+@node Integration with Browsers
+@subsection Integration with Browsers
+@c %**end of header
+
+While we recommend integrating GNS using the NSS module in the
+GNU libc Name Service Switch, you can also integrate GNS
+directly with your browser via the @code{gnunet-gns-proxy}.
+This method can have the advantage that the proxy can validate
+TLS/X.509 records and thus strengthen web security; however, the proxy
+is still a bit brittle, so expect subtle failures. We have had reasonable
+success with Chromium, and various frustrations with Firefox in this area
+recently.
+
+The first step is to start the proxy. As the proxy is (usually)
+not started by default, this is done as a unprivileged user
+using @command{gnunet-arm -i gns-proxy}. Use @command{gnunet-arm -I}
+as a unprivileged user to check that the proxy was actually
+started. (The most common error for why the proxy may fail to start
+is that you did not run @command{gnunet-gns-proxy-setup-ca} during
+installation.) The proxy is a SOCKS5 proxy running (by default)
+on port 7777. Thus, you need to now configure your browser to use
+this proxy. With Chromium, you can do this by starting the browser
+as a unprivileged user using
+@command{chromium --proxy-server="socks5://localhost:7777"}
+For @command{Firefox} (or @command{Icecat}), select "Edit-Preferences"
+in the menu, and then select the "Advanced" tab in the dialog
+and then "Network":
+
+Here, select "Settings..." to open the proxy settings dialog.
+Select "Manual proxy configuration" and enter "localhost"
+with port 7777 under SOCKS Host. Select SOCKS v5 and then push "OK".
+
+You must also go to about:config and change the
+@code{browser.fixup.alternate.enabled} option to @code{false},
+otherwise the browser will autoblunder an address like
+@code{@uref{http://www.gnu/, www.gnu}} to
+@code{@uref{http://www.gnu.com/, www.gnu.com}}.
+
+After configuring your browser, you might want to first confirm that it
+continues to work as before. (The proxy is still experimental and if you
+experience "odd" failures with some webpages, you might want to disable
+it again temporarily.) Next, test if things work by typing
+"@uref{http://test.gnu/}" into the URL bar of your browser.
+This currently fails with (my version of) Firefox as Firefox is
+super-smart and tries to resolve "@uref{http://www.test.gnu/}" instead of
+"@uref{test.gnu}". Chromium can be convinced to comply if you explicitly
+include the "http://" prefix --- otherwise a Google search might be
+attempted, which is not what you want. If successful, you should
+see a simple website.
+
+Note that while you can use GNS to access ordinary websites, this is
+more an experimental feature and not really our primary goal at this
+time. Still, it is a possible use-case and we welcome help with testing
+and development.
+
+@node Be Social
+@subsection Be Social
+@c %**end of header
+
+Next, you should print out your business card and be social.
+Find a friend, help them install GNUnet and exchange business cards with
+them. Or, if you're a desperate loner, you might try the next step with
+your own card. Still, it'll be hard to have a conversation with
+yourself later, so it would be better if you could find a friend.
+You might also want a camera attached to your computer, so
+you might need a trip to the store together. Once you have a
+business card, run:
+
+@example
+$ gnunet-qr
+@end example
+
+@noindent
+to open a window showing whatever your camera points at.
+Hold up your friend's business card and tilt it until
+the QR code is recognized. At that point, the window should
+automatically close. At that point, your friend's NICKname and their
+public key should have been automatically imported into your zone.
+Assuming both of your peers are properly integrated in the
+GNUnet network at this time, you should thus be able to
+resolve your friends names. Suppose your friend's nickname
+is "Bob". Then, type
+
+@example
+$ gnunet-gns -u test.bob.gnu
+@end example
+
+@noindent
+to check if your friend was as good at following instructions
+as you were.
+
+
+@node Backup of Identities and Egos
+@subsection Backup of Identities and Egos
+
+
+One should always backup their files, especially in these SSD days (our
+team has suffered 3 SSD crashes over a span of 2 weeks). Backing up peer
+identity and zones is achieved by copying the following files:
+
+The peer identity file can be found
+in @file{~/.local/share/gnunet/private_key.ecc}
+
+The private keys of your egos are stored in the
+directory @file{~/.local/share/gnunet/identity/egos/}.
+They are stored in files whose filenames correspond to the zones'
+ego names. These are probably the most important files you want
+to backup from a GNUnet installation.
+
+Note: All these files contain cryptographic keys and they are
+stored without any encryption. So it is advisable to backup
+encrypted copies of them.
+
+@node Revocation
+@subsection Revocation
+
+Now, in the situation of an attacker gaining access to the private key of
+one of your egos, the attacker can create records in the respective
+GNS zone
+and publish them as if you published them. Anyone resolving your
+domain will get these new records and when they verify they seem
+authentic because the attacker has signed them with your key.
+
+To address this potential security issue, you can pre-compute
+a revocation certificate corresponding to your ego. This certificate,
+when published on the P2P network, flags your private key as invalid,
+and all further resolutions or other checks involving the key will fail.
+
+A revocation certificate is thus a useful tool when things go out of
+control, but at the same time it should be stored securely.
+Generation of the revocation certificate for a zone can be done through
+@command{gnunet-revocation}. For example, the following command (as
+unprivileged user) generates a revocation file
+@file{revocation.dat} for the zone @code{zone1}:
+@command{gnunet-revocation -f revocation.dat -R zone1}
+
+The above command only pre-computes a revocation certificate. It does
+not revoke the given zone. Pre-computing a revocation certificate
+involves computing a proof-of-work and hence may take upto 4 to 5 days
+on a modern processor. Note that you can abort and resume the
+calculation at any time. Also, even if you did not finish the
+calculation, the resulting file will contain the signature, which is
+sufficient to complete the revocation process even without access to
+the private key. So instead of waiting for a few days, you can just
+abort with CTRL-C, backup the revocation certificate and run the
+calculation only if your key actually was compromised. This has the
+disadvantage of revocation taking longer after the incident, but
+the advantage of saving a significant amount of energy. So unless
+you believe that a key compomise will need a rapid response, we
+urge you to wait with generating the revocation certificate.
+Also, the calculation is deliberately expensive, to deter people from
+doing this just for fun (as the actual revocation operation is expensive
+for the network, not for the peer performing the revocation).
+
+To avoid TL;DR ones from accidentally revocating their zones, I am not
+giving away the command, but its simple: the actual revocation is
+performed by using the @command{-p} option
+of @command{gnunet-revocation}.
+
+
+
+@node What's Next?
+@subsection What's Next?
+@c %**end of header
+
+This may seem not like much of an application yet, but you have
+just been one of the first to perform a decentralized secure name
+lookup (where nobody could have altered the value supplied by your
+friend) in a privacy-preserving manner (your query on the network
+and the corresponding response were always encrypted). So what
+can you really do with this? Well, to start with, you can publish your
+GnuPG fingerprint in GNS as a "CERT" record and replace the public
+web-of-trust with its complicated trust model with explicit names
+and privacy-preserving resolution. Also, you should read the next
+chapter of the tutorial and learn how to use GNS to have a
+private conversation with your friend. Finally, help us
+with the next GNUnet release for even more applications
+using this new public key infrastructure.
+
+@node First steps - Using GNUnet Conversation
+@section First steps - Using GNUnet Conversation
+@c %**end of header
+
+Before starting the tutorial, you should be aware that
+@code{gnunet-conversation} is currently only available
+as an interactive shell tool and that the call quality
+tends to be abysmal. There are also some awkward
+steps necessary to use it. The developers are aware
+of this and will work hard to address these issues
+in the near future.
+
+
+@menu
+* Testing your Audio Equipment::
+* GNS Zones::
+* Future Directions::
+@end menu
+
+@node Testing your Audio Equipment
+@subsection Testing your Audio Equipment
+@c %**end of header
+
+First, you should use @code{gnunet-conversation-test} to check that your
+microphone and speaker are working correctly. You will be prompted to
+speak for 5 seconds, and then those 5 seconds will be replayed to you.
+The network is not involved in this test. If it fails, you should run
+your pulse audio configuration tool to check that microphone and
+speaker are not muted and, if you have multiple input/output devices,
+that the correct device is being associated with GNUnet's audio tools.
+
+@node GNS Zones
+@subsection GNS Zones
+@c %**end of header
+
+@code{gnunet-conversation} uses GNS for addressing. This means that
+you need to have a GNS zone created before using it. Information
+about how to create GNS zones can be found here.
+
+
+@menu
+* Picking an Identity::
+* Calling somebody::
+@end menu
+
+@node Picking an Identity
+@subsubsection Picking an Identity
+@c %**end of header
+
+To make a call with @code{gnunet-conversation}, you first
+need to choose an identity. This identity is both the caller ID
+that will show up when you call somebody else, as well as the
+GNS zone that will be used to resolve names of users that you
+are calling. Usually, the @code{master-zone} is a reasonable
+choice. Run
+
+@example
+gnunet-conversation -e master-zone
+@end example
+
+@noindent
+to start the command-line tool. You will see a message saying
+that your phone is now "active on line 0". You can connect
+multiple phones on different lines at the same peer. For the
+first phone, the line zero is of course a fine choice.
+
+Next, you should type in @command{/help} for a list of
+available commands. We will explain the important ones
+during this tutorial. First, you will need to type in
+@command{/address} to determine the address of your
+phone. The result should look something like this:
+
+@example
+/address
+0-PD67SGHF3E0447TU9HADIVU9OM7V4QHTOG0EBU69TFRI2LG63DR0
+@end example
+
+@noindent
+Here, the "0" is your phone line, and what follows
+after the hyphen is your peer's identity. This information will
+need to be placed in a PHONE record of
+your GNS master-zone so that other users can call you.
+
+Start @code{gnunet-namestore-gtk} now (possibly from another
+shell) and create an entry home-phone in your master zone.
+For the record type, select PHONE. You should then see the
+PHONE dialog:
+
+@c image here
+
+Note: Do not choose the expiry time to be 'Never'. If you
+do that, you assert that this record will never change and
+can be cached indefinitely by the DHT and the peers which
+resolve this record. A reasonable period is 1 year.
+
+Enter your peer identity under Peer and leave the line
+at zero. Select the first option to make the record public.
+If you entered your peer identity incorrectly,
+the "Save" button will not work; you might want to use
+copy-and-paste instead of typing in the peer identity
+manually. Save the record.
+
+@node Calling somebody
+@subsubsection Calling somebody
+@c %**end of header
+
+Now you can call a buddy. Obviously, your buddy will have to have GNUnet
+installed and must have performed the same steps. Also, you must have
+your buddy in your GNS master zone, for example by having imported
+your buddy's public key using @code{gnunet-qr}. Suppose your buddy
+is in your zone as @code{buddy.gnu} and they also created their
+phone using a label "home-phone". Then you can initiate a call using:
+
+@example
+/call home-phone.buddy.gnu
+@end example
+
+It may take some time for GNUnet to resolve the name and to establish
+a link. If your buddy has your public key in their master zone, they
+should see an incoming call with your name. If your public key is not
+in their master zone, they will just see the public key as the caller ID.
+
+Your buddy then can answer the call using the "/accept" command. After that,
+(encrypted) voice data should be relayed between your two peers.
+Either of you can end the call using @command{/cancel}. You can exit
+@code{gnunet-converation} using @command{/quit}.
+
+@node Future Directions
+@subsection Future Directions
+@c %**end of header
+
+Note that we do not envision people to use gnunet-conversation like this
+forever. We will write a graphical user interface, and that GUI will
+automatically create the necessary records in the respective zone.
+
+@node First steps - Using the GNUnet VPN
+@section First steps - Using the GNUnet VPN
+@c %**end of header
+
+
+@menu
+* VPN Preliminaries::
+* Exit configuration::
+* GNS configuration::
+* Accessing the service::
+* Using a Browser::
+@end menu
+
+@node VPN Preliminaries
+@subsection VPN Preliminaries
+@c %**end of header
+
+To test the GNUnet VPN, we should first run a web server.
+The easiest way to do this is to just start @code{gnunet-bcd},
+which will run a webserver on port @code{8888} by default.
+Naturally, you can run some other HTTP server for our little tutorial.
+
+If you have not done this, you should also configure your
+Name System Service switch to use GNS. In your @code{/etc/nsswitch.conf}
+you should fine a line like this:
+
+@example
+hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4
+@end example
+
+@noindent
+The exact details may differ a bit, which is fine. Add the text
+@code{gns [NOTFOUND=return]} after @code{files}:
+
+@example
+hosts: files gns [NOTFOUND=return] mdns4_minimal [NOTFOUND=return] dns mdns4
+@end example
+
+@noindent
+You might want to make sure that @code{/lib/libnss_gns.so.2} exists on
+your system, it should have been created during the installation.
+If not, re-run
+
+@example
+$ configure --with-nssdir=/lib
+$ cd src/gns/nss; sudo make install
+@end example
+
+@noindent
+to install the NSS plugins in the proper location.
+
+@node Exit configuration
+@subsection Exit configuration
+@c %**end of header
+
+Stop your peer (as user @code{gnunet}, run @code{gnunet-arm -e}) and run
+@code{gnunet-setup}. In @code{gnunet-setup}, make sure to activate the
+@strong{EXIT} and @strong{GNS} services in the General tab. Then select
+the Exit tab. Most of the defaults should be fine (but you should check
+against the screenshot that they have not been modified). In the
+bottom area, enter @code{bcd} under Identifier and change the
+Destination to @code{169.254.86.1:8888} (if your server runs on a port
+other than 8888, change the 8888 port accordingly).
+
+Now exit @code{gnunet-setup} and restart your peer (@code{gnunet-arm -s}).
+
+@node GNS configuration
+@subsection GNS configuration
+@c %**end of header
+
+Now, using your normal user (not the @code{gnunet} system user), run
+@code{gnunet-gtk}. Select the GNS icon and add a new label www in your
+master zone. For the record type, select @code{VPN}. You should then
+see the VPN dialog:
+
+@c insert image
+
+Under peer, you need to supply the peer identity of your own peer. You can
+obtain the respective string by running @code{ $ gnunet-peerinfo -sq}
+as the @code{gnunet} user. For the Identifier, you need to supply the same
+identifier that we used in the Exit setup earlier, so here supply "bcd".
+If you want others to be able to use the service, you should probably make
+the record public. For non-public services, you should use a passphrase
+instead of the string "bcd". Save the record and exit @code{gnunet-gtk}.
+
+@node Accessing the service
+@subsection Accessing the service
+@c %**end of header
+
+You should now be able to access your webserver. Type in:
+
+@example
+$ wget http://www.gnu/
+@end example
+
+@noindent
+The request will resolve to the VPN record, telling the GNS resolver
+to route it via the GNUnet VPN. The GNS resolver will ask the
+GNUnet VPN for an IPv4 address to return to the application. The
+VPN service will use the VPN information supplied by GNS to create
+a tunnel (via GNUnet's MESH service) to the EXIT peer.
+At the EXIT, the name "bcd" and destination port (80) will be mapped
+to the specified destination IP and port. While all this is currently
+happening on just the local machine, it should also work with other
+peers --- naturally, they will need a way to access your GNS zone
+first, for example by learning your public key from a QR code on
+your business card.
+
+@node Using a Browser
+@subsection Using a Browser
+@c %**end of header
+
+Sadly, modern browsers tend to bypass the Name Services Switch and
+attempt DNS resolution directly. You can either run
+a @code{gnunet-dns2gns} DNS proxy, or point the browsers to an
+HTTP proxy. When we tried it, Iceweasel did not like to connect to
+the socks proxy for @code{.gnu} TLDs, even if we disabled its
+autoblunder of changing @code{.gnu} to ".gnu.com". Still,
+using the HTTP proxy with Chrome does work.
+
+@node File-sharing
+@section File-sharing
+@c %**end of header
+
+This chapter documents the GNUnet file-sharing application. The original
+file-sharing implementation for GNUnet was designed to provide
+@strong{anonymous} file-sharing. However, over time, we have also added
+support for non-anonymous file-sharing (which can provide better
+performance). Anonymous and non-anonymous file-sharing are quite
+integrated in GNUnet and, except for routing, share most of the concepts
+and implementation. There are three primary file-sharing operations:
+publishing, searching and downloading. For each of these operations,
+the user specifies an @strong{anonymity level}. If both the publisher and
+the searcher/downloader specify "no anonymity", non-anonymous
+file-sharing is used. If either user specifies some desired degree
+of anonymity, anonymous file-sharing will be used.
+
+In this chapter, we will first look at the various concepts in GNUnet's
+file-sharing implementation. Then, we will discuss specifics as to
+how they impact users that publish, search or download files.
+
+
+
+@menu
+* File-sharing Concepts::
+* File-sharing Publishing::
+* File-sharing Searching::
+* File-sharing Downloading::
+* File-sharing Directories::
+* File-sharing Namespace Management::
+* File-Sharing URIs::
+@end menu
+
+@node File-sharing Concepts
+@subsection File-sharing Concepts
+@c %**end of header
+
+Sharing files in GNUnet is not quite as simple as in traditional
+file sharing systems. For example, it is not sufficient to just
+place files into a specific directory to share them. In addition
+to anonymous routing GNUnet attempts to give users a better experience
+in searching for content. GNUnet uses cryptography to safely break
+content into smaller pieces that can be obtained from different
+sources without allowing participants to corrupt files. GNUnet
+makes it difficult for an adversary to send back bogus search
+results. GNUnet enables content providers to group related content
+and to establish a reputation. Furthermore, GNUnet allows updates
+to certain content to be made available. This section is supposed
+to introduce users to the concepts that are used to achive these goals.
+
+
+@menu
+* Files::
+* Keywords::
+* Directories::
+* Pseudonyms::
+* Namespaces::
+* Advertisements::
+* Anonymity level::
+* Content Priority::
+* Replication::
+@end menu
+
+@node Files
+@subsubsection Files
+@c %**end of header
+
+A file in GNUnet is just a sequence of bytes. Any file-format is allowed
+and the maximum file size is theoretically 264 bytes, except that it
+would take an impractical amount of time to share such a file.
+GNUnet itself never interprets the contents of shared files, except
+when using GNU libextractor to obtain keywords.
+
+@node Keywords
+@subsubsection Keywords
+@c %**end of header
+
+Keywords are the most simple mechanism to find files on GNUnet.
+Keywords are @strong{case-sensitive} and the search string
+must always match @strong{exactly} the keyword used by the
+person providing the file. Keywords are never transmitted in
+plaintext. The only way for an adversary to determine the keyword
+that you used to search is to guess it (which then allows the
+adversary to produce the same search request). Since providing
+keywords by hand for each shared file is tedious, GNUnet uses
+GNU libextractor to help automate this process. Starting a
+keyword search on a slow machine can take a little while since
+the keyword search involves computing a fresh RSA key to formulate the
+request.
+
+@node Directories
+@subsubsection Directories
+@c %**end of header
+
+A directory in GNUnet is a list of file identifiers with meta data.
+The file identifiers provide sufficient information about the files
+to allow downloading the contents. Once a directory has been created,
+it cannot be changed since it is treated just like an ordinary file
+by the network. Small files (of a few kilobytes) can be inlined in
+the directory, so that a separate download becomes unnecessary.
+
+@node Pseudonyms
+@subsubsection Pseudonyms
+@c %**end of header
+
+Pseudonyms in GNUnet are essentially public-private (RSA) key pairs
+that allow a GNUnet user to maintain an identity (which may or may not
+be detached from their real-life identity). GNUnet's pseudonyms are not
+file-sharing specific --- and they will likely be used by many GNUnet
+applications where a user identity is required.
+
+Note that a pseudonym is NOT bound to a GNUnet peer. There can be multiple
+pseudonyms for a single user, and users could (theoretically) share the
+private pseudonym keys (currently only out-of-band by knowing which files
+to copy around).
+
+@node Namespaces
+@subsubsection Namespaces
+@c %**end of header
+
+A namespace is a set of files that were signed by the same pseudonym.
+Files (or directories) that have been signed and placed into a namespace
+can be updated. Updates are identified as authentic if the same secret
+key was used to sign the update. Namespaces are also useful to establish
+a reputation, since all of the content in the namespace comes from the
+same entity (which does not have to be the same person).
+
+@node Advertisements
+@subsubsection Advertisements
+@c %**end of header
+
+Advertisements are used to notify other users about the existence of a
+namespace. Advertisements are propagated using the normal keyword search.
+When an advertisement is received (in response to a search), the namespace
+is added to the list of namespaces available in the namespace-search
+dialogs of gnunet-fs-gtk and printed by gnunet-pseudonym. Whenever a
+namespace is created, an appropriate advertisement can be generated.
+The default keyword for the advertising of namespaces is "namespace".
+
+Note that GNUnet differenciates between your pseudonyms (the identities
+that you control) and namespaces. If you create a pseudonym, you will
+not automatically see the respective namespace. You first have to create
+an advertisement for the namespace and find it using keyword
+search --- even for your own namespaces. The @code{gnunet-pseudonym}
+tool is currently responsible for both managing pseudonyms and namespaces.
+This will likely change in the future to reduce the potential for
+confusion.
+
+@node Anonymity level
+@subsubsection Anonymity level
+@c %**end of header
+
+The anonymity level determines how hard it should be for an adversary to
+determine the identity of the publisher or the searcher/downloader. An
+anonymity level of zero means that anonymity is not required. The default
+anonymity level of "1" means that anonymous routing is desired, but no
+particular amount of cover traffic is necessary. A powerful adversary
+might thus still be able to deduce the origin of the traffic using
+traffic analysis. Specifying higher anonymity levels increases the
+amount of cover traffic required. While this offers better privacy,
+it can also significantly hurt performance.
+
+@node Content Priority
+@subsubsection Content Priority
+@c %**end of header
+
+Depending on the peer's configuration, GNUnet peers migrate content
+between peers. Content in this sense are individual blocks of a file,
+not necessarily entire files. When peers run out of space (due to
+local publishing operations or due to migration of content from other
+peers), blocks sometimes need to be discarded. GNUnet first always
+discards expired blocks (typically, blocks are published with an
+expiration of about two years in the future; this is another option).
+If there is still not enough space, GNUnet discards the blocks with the
+lowest priority. The priority of a block is decided by its popularity
+(in terms of requests from peers we trust) and, in case of blocks
+published locally, the base-priority that was specified by the user
+when the block was published initially.
+
+@node Replication
+@subsubsection Replication
+@c %**end of header
+
+When peers migrate content to other systems, the replication level
+of a block is used to decide which blocks need to be migrated most
+urgently. GNUnet will always push the block with the highest
+replication level into the network, and then decrement the replication
+level by one. If all blocks reach replication level zero, the
+selection is simply random.
+
+@node File-sharing Publishing
+@subsection File-sharing Publishing
+@c %**end of header
+
+The command @code{gnunet-publish} can be used to add content
+to the network. The basic format of the command is
+
+@example
+$ gnunet-publish [-n] [-k KEYWORDS]* [-m TYPE:VALUE] FILENAME
+@end example
+
+
+@menu
+* Important command-line options::
+* Indexing vs. Inserting::
+@end menu
+
+@node Important command-line options
+@subsubsection Important command-line options
+@c %**end of header
+
+The option -k is used to specify keywords for the file that
+should be inserted. You can supply any number of keywords,
+and each of the keywords will be sufficient to locate and
+retrieve the file.
+
+The -m option is used to specify meta-data, such as descriptions.
+You can use -m multiple times. The TYPE passed must be from the
+list of meta-data types known to libextractor. You can obtain this
+list by running @code{extract -L}. Use quotes around the entire
+meta-data argument if the value contains spaces. The meta-data
+is displayed to other users when they select which files to
+download. The meta-data and the keywords are optional and
+maybe inferred using @code{GNU libextractor}.
+
+gnunet-publish has a few additional options to handle namespaces and
+directories. See the man-page for details.
+
+@node Indexing vs. Inserting
+@subsubsection Indexing vs Inserting
+@c %**end of header
+
+By default, GNUnet indexes a file instead of making a full copy.
+This is much more efficient, but requries the file to stay unaltered
+at the location where it was when it was indexed. If you intend to move,
+delete or alter a file, consider using the option @code{-n} which will
+force GNUnet to make a copy of the file in the database.
+
+Since it is much less efficient, this is strongly discouraged for large
+files. When GNUnet indexes a file (default), GNUnet does @strong{not}
+create an additional encrypted copy of the file but just computes a
+summary (or index) of the file. That summary is approximately two percent
+of the size of the original file and is stored in GNUnet's database.
+Whenever a request for a part of an indexed file reaches GNUnet,
+this part is encrypted on-demand and send out. This way, there is no
+need for an additional encrypted copy of the file to stay anywhere
+on the drive. This is different from other systems, such as Freenet,
+where each file that is put online must be in Freenet's database in
+encrypted format, doubling the space requirements if the user wants
+to preseve a directly accessible copy in plaintext.
+
+Thus indexing should be used for all files where the user will keep
+using this file (at the location given to gnunet-publish) and does
+not want to retrieve it back from GNUnet each time. If you want to
+remove a file that you have indexed from the local peer, use the tool
+@code{gnunet-unindex} to un-index the file.
+
+The option @code{-n} may be used if the user fears that the file might
+be found on their drive (assuming the computer comes under the control
+of an adversary). When used with the @code{-n} flag, the user has a
+much better chance of denying knowledge of the existence of the file,
+even if it is still (encrypted) on the drive and the adversary is
+able to crack the encryption (e.g. by guessing the keyword.
+
+@node File-sharing Searching
+@subsection File-sharing Searching
+@c %**end of header
+
+The command @code{gnunet-search} can be used to search
+for content on GNUnet. The format is:
+
+@example
+$ gnunet-search [-t TIMEOUT] KEYWORD
+@end example
+
+@noindent
+The -t option specifies that the query should timeout after
+approximately TIMEOUT seconds. A value of zero is interpreted
+as @emph{no timeout}, which is also the default. In this case,
+gnunet-search will never terminate (unless you press CTRL-C).
+
+If multiple words are passed as keywords, they will all be
+considered optional. Prefix keywords with a "+" to make them mandatory.
+
+Note that searching using
+
+@example
+$ gnunet-search Das Kapital
+@end example
+
+@noindent
+is not the same as searching for
+
+@example
+$ gnunet-search "Das Kapital"
+@end example
+
+@noindent
+as the first will match files shared under the keywords
+"Das" or "Kapital" whereas the second will match files
+shared under the keyword "Das Kapital".
+
+Search results are printed by gnunet-search like this:
+
+@example
+$ gnunet-download -o "COPYING" --- gnunet://fs/chk/N8...C92.17992
+=> The GNU Public License <= (mimetype: text/plain)
+@end example
+
+@noindent
+The first line is the command you would have to enter to download
+the file. The argument passed to @code{-o} is the suggested
+filename (you may change it to whatever you like).
+The @code{--} is followed by key for decrypting the file,
+the query for searching the file, a checksum (in hexadecimal)
+finally the size of the file in bytes.
+The second line contains the description of the file; here this is
+"The GNU Public License" and the mime-type (see the options for
+gnunet-publish on how to specify these).
+
+@node File-sharing Downloading
+@subsection File-sharing Downloading
+@c %**end of header
+
+In order to download a file, you need the three values returned by
+@code{gnunet-search}.
+You can then use the tool @code{gnunet-download} to obtain the file:
+
+@example
+$ gnunet-download -o FILENAME --- GNUNETURL
+@end example
+
+@noindent
+FILENAME specifies the name of the file where GNUnet is supposed
+to write the result. Existing files are overwritten. If the
+existing file contains blocks that are identical to the
+desired download, those blocks will not be downloaded again
+(automatic resume).
+
+If you want to download the GPL from the previous example,
+you do the following:
+
+@example
+$ gnunet-download -o "COPYING" --- gnunet://fs/chk/N8...92.17992
+@end example
+
+@noindent
+If you ever have to abort a download, you can continue it at any time by
+re-issuing @command{gnunet-download} with the same filename.
+In that case, GNUnet will @strong{not} download blocks again that are
+already present.
+
+GNUnet's file-encoding mechanism will ensure file integrity, even if the
+existing file was not downloaded from GNUnet in the first place.
+
+You may want to use the @command{-V} switch (must be added before
+the @command{--}) to turn on verbose reporting. In this case,
+@command{gnunet-download} will print the current number of
+bytes downloaded whenever new data was received.
+
+@node File-sharing Directories
+@subsection File-sharing Directories
+@c %**end of header
+
+Directories are shared just like ordinary files. If you download a
+directory with @command{gnunet-download}, you can use
+@command{gnunet-directory} to list its contents. The canonical
+extension for GNUnet directories when stored as files in your
+local file-system is ".gnd". The contents of a directory are URIs and
+meta data.
+The URIs contain all the information required by
+@command{gnunet-download} to retrieve the file. The meta data
+typically includes the mime-type, description, a filename and
+other meta information, and possibly even the full original file
+(if it was small).
+
+@node File-sharing Namespace Management
+@subsection File-sharing Namespace Management
+@c %**end of header
+
+@b{Please note that the text in this subsection is outdated and needs}
+@b{to be rewritten for version 0.10!}
+
+The gnunet-pseudonym tool can be used to create pseudonyms and
+to advertise namespaces. By default, gnunet-pseudonym simply
+lists all locally available pseudonyms.
+
+
+@menu
+* Creating Pseudonyms::
+* Deleting Pseudonyms::
+* Advertising namespaces::
+* Namespace names::
+* Namespace root::
+@end menu
+
+@node Creating Pseudonyms
+@subsubsection Creating Pseudonyms
+@c %**end of header
+
+With the @command{-C NICK} option it can also be used to
+create a new pseudonym. A pseudonym is the virtual identity
+of the entity in control of a namespace. Anyone can create
+any number of pseudonyms. Note that creating a pseudonym can
+take a few minutes depending on the performance of the machine
+used.
+
+@node Deleting Pseudonyms
+@subsubsection Deleting Pseudonyms
+@c %**end of header
+
+With the @command{-D NICK} option pseudonyms can be deleted.
+Once the pseudonym has been deleted it is impossible to add
+content to the corresponding namespace. Deleting the
+pseudonym does not make the namespace or any content in it
+unavailable.
+
+@node Advertising namespaces
+@subsubsection Advertising namespaces
+@c %**end of header
+
+Each namespace is associated with meta-data that describes
+the namespace. This meta data is provided by the user at
+the time that the namespace is advertised. Advertisements
+are published under keywords so that they can be found using
+normal keyword-searches. This way, users can learn about new
+namespaces without relying on out-of-band communication or directories.
+A suggested keyword to use for all namespaces is simply "namespace".
+When a keyword-search finds a namespace advertisement,
+it is automatically stored in a local list of known namespaces.
+Users can then associate a rank with the namespace to remember
+the quality of the content found in it.
+
+@node Namespace names
+@subsubsection Namespace names
+@c %**end of header
+
+While the namespace is uniquely identified by its ID, another way
+to refer to the namespace is to use the NICKNAME.
+The NICKNAME can be freely chosen by the creator of the namespace and
+hence conflicts are possible. If a GNUnet client learns about more
+than one namespace using the same NICKNAME, the ID is appended
+to the NICKNAME to get a unique identifier.
+
+@node Namespace root
+@subsubsection Namespace root
+@c %**end of header
+
+An item of particular interest in the namespace advertisement is
+the ROOT. The ROOT is the identifier of a designated entry in the
+namespace. The idea is that the ROOT can be used to advertise an
+entry point to the content of the namespace.
+
+@node File-Sharing URIs
+@subsection File-Sharing URIs
+@c %**end of header
+
+GNUnet (currently) uses four different types of URIs for
+file-sharing. They all begin with "gnunet://fs/".
+This section describes the four different URI types in detail.
+
+
+@menu
+* Encoding of hash values in URIs::
+* Content Hash Key (chk)::
+* Location identifiers (loc)::
+* Keyword queries (ksk)::
+* Namespace content (sks)::
+@end menu
+
+@node Encoding of hash values in URIs
+@subsubsection Encoding of hash values in URIs
+@c %**end of header
+
+Most URIs include some hash values. Hashes are encoded using
+base32hex (RFC 2938).
+
+@node Content Hash Key (chk)
+@subsubsection Content Hash Key (chk)
+@c %**end of header
+
+A chk-URI is used to (uniquely) identify a file or directory
+and to allow peers to download the file. Files are stored in
+GNUnet as a tree of encrypted blocks.
+The chk-URI thus contains the information to download and decrypt
+those blocks. A chk-URI has the format
+"gnunet://fs/chk/KEYHASH.QUERYHASH.SIZE". Here, "SIZE"
+is the size of the file (which allows a peer to determine the
+shape of the tree), KEYHASH is the key used to decrypt the file
+(also the hash of the plaintext of the top block) and QUERYHASH
+is the query used to request the top-level block (also the hash
+of the encrypted block).
+
+@node Location identifiers (loc)
+@subsubsection Location identifiers (loc)
+@c %**end of header
+
+For non-anonymous file-sharing, loc-URIs are used to specify which
+peer is offering the data (in addition to specifying all of the
+data from a chk-URI). Location identifiers include a digital
+signature of the peer to affirm that the peer is truly the
+origin of the data. The format is
+"gnunet://fs/loc/KEYHASH.QUERYHASH.SIZE.PEER.SIG.EXPTIME".
+Here, "PEER" is the public key of the peer (in GNUnet format in
+base32hex), SIG is the RSA signature (in GNUnet format in
+base32hex) and EXPTIME specifies when the signature expires
+(in milliseconds after 1970).
+
+@node Keyword queries (ksk)
+@subsubsection Keyword queries (ksk)
+@c %**end of header
+
+A keyword-URI is used to specify that the desired operation
+is the search using a particular keyword. The format is simply
+"gnunet://fs/ksk/KEYWORD". Non-ASCII characters can be specified
+using the typical URI-encoding (using hex values) from HTTP.
+"+" can be used to specify multiple keywords (which are then
+logically "OR"-ed in the search, results matching both keywords
+are given a higher rank): "gnunet://fs/ksk/KEYWORD1+KEYWORD2".
+
+@node Namespace content (sks)
+@subsubsection Namespace content (sks)
+@c %**end of header
+
+Namespaces are sets of files that have been approved by some (usually
+pseudonymous) user --- typically by that user publishing all of the
+files together. A file can be in many namespaces. A file is in a
+namespace if the owner of the ego (aka the namespace's private key)
+signs the CHK of the file cryptographically. An SKS-URI is used to
+search a namespace. The result is a block containing meta data,
+the CHK and the namespace owner's signature. The format of a sks-URI
+is "gnunet://fs/sks/NAMESPACE/IDENTIFIER". Here, "NAMESPACE"
+is the public key for the namespace. "IDENTIFIER" is a freely
+chosen keyword (or password!). A commonly used identifier is
+"root" which by convention refers to some kind of index or other
+entry point into the namespace.
+
+@node The GNU Name System
+@section The GNU Name System
+@c %**end of header
+
+
+The GNU Name System (GNS) is secure and decentralized naming system.
+It allows its users to resolve and register names within the @code{.gnu}
+@dfn{top-level domain} (TLD).
+
+GNS is designed to provide:
+@itemize @bullet
+@item Censorship resistance
+@item Query privacy
+@item Secure name resolution
+@item Compatibility with DNS
+@end itemize
+
+For the initial configuration and population of your
+GNS installation, please follow the GNS setup instructions.
+The remainder of this chapter will provide some background on GNS
+and then describe how to use GNS in more detail.
+
+Unlike DNS, GNS does not rely on central root zones or authorities.
+Instead any user administers their own root and can can create arbitrary
+name value mappings. Furthermore users can delegate resolution to other
+users' zones just like DNS NS records do. Zones are uniquely identified
+via public keys and resource records are signed using the corresponding
+public key. Delegation to another user's zone is done using special PKEY
+records and petnames. A petname is a name that can be freely chosen by
+the user. This results in non-unique name-value mappings as
+@code{@uref{http://www.bob.gnu/, www.bob.gnu}} to one user might be
+@code{@uref{http://www.friend.gnu/, www.friend.gnu}} for someone else.
+
+
+@menu
+* Maintaining your own Zones::
+* Obtaining your Zone Key::
+* Adding Links to Other Zones::
+* The Three Local Zones of GNS::
+* The Master Zone::
+* The Private Zone::
+* The Shorten Zone::
+* The ZKEY Top Level Domain in GNS::
+* Resource Records in GNS::
+@end menu
+
+
+@node Maintaining your own Zones
+@subsection Maintaining your own Zones
+
+To setup your GNS system you must execute:
+
+@example
+$ gnunet-gns-import.sh
+@end example
+
+@noindent
+This will boostrap your zones and create the necessary key material.
+Your keys can be listed using the @command{gnunet-identity}
+command line tool:
+
+@example
+$ gnunet-identity -d
+@end example
+
+@noindent
+You can arbitrarily create your own zones using the gnunet-identity
+tool using:
+
+@example
+$ gnunet-identity -C "new_zone"
+@end example
+
+@noindent
+Now you can add (or edit, or remove) records in your GNS zone using the
+gnunet-setup GUI or using the gnunet-namestore command-line tool.
+In either case, your records will be stored in an SQL database under
+control of the gnunet-service-namestore. Note that if multiple users
+use one peer, the namestore database will include the combined records
+of all users. However, users will not be able to see each other's records
+if they are marked as private.
+
+To provide a simple example for editing your own zone, suppose you
+have your own web server with IP 1.2.3.4. Then you can put an
+A record (A records in DNS are for IPv4 IP addresses) into your
+local zone using the command:
+
+@example
+$ gnunet-namestore -z master-zone -a -n www -t A -V 1.2.3.4 -e never
+@end example
+
+@noindent
+Afterwards, you will be able to access your webpage under "www.gnu"
+(assuming your webserver does not use virtual hosting, if it does,
+please read up on setting up the GNS proxy).
+
+Similar commands will work for other types of DNS and GNS records,
+the syntax largely depending on the type of the record.
+Naturally, most users may find editing the zones using the
+@command{gnunet-setup} GUI to be easier.
+
+@node Obtaining your Zone Key
+@subsection Obtaining your Zone Key
+
+Each zone in GNS has a public-private key. Usually, gnunet-namestore and
+gnunet-setup will access your private key as necessary, so you do not
+have to worry about those. What is important is your public key
+(or rather, the hash of your public key), as you will likely want to
+give it to others so that they can securely link to you.
+
+You can usually get the hash of your public key using
+
+@example
+$ gnunet-identity -d $options | grep master-zone | awk '@{print $3@}'
+@end example
+
+@noindent
+For example, the output might be something like:
+
+@example
+DC3SEECJORPHQNVRH965A6N74B1M37S721IG4RBQ15PJLLPJKUE0
+@end example
+
+@noindent
+Alternatively, you can obtain a QR code with your zone key AND
+your pseudonym from gnunet-gtk. The QR code is displayed in the
+GNS tab and can be stored to disk using the Save as button next
+to the image.
+
+@node Adding Links to Other Zones
+@subsection Adding Links to Other Zones
+
+
+A central operation in GNS is the ability to securely delegate to
+other zones. Basically, by adding a delegation you make all of the
+names from the other zone available to yourself. This section
+describes how to create delegations.
+
+Suppose you have a friend who you call 'bob' who also uses GNS.
+You can then delegate resolution of names to Bob's zone by adding
+a PKEY record to their local zone:
+
+@example
+$ gnunet-namestore -a -n bob --type PKEY -V XXXX -e never
+@end example
+
+@noindent
+Note that XXXX in the command above must be replaced with the
+hash of Bob's public key (the output your friend obtained using
+the gnunet-identity command from the previous section and told you,
+for example by giving you a business card containing this
+information as a QR code).
+
+Assuming Bob has an A record for their website under the name of
+www in his zone, you can then access Bob's website under
+www.bob.gnu --- as well as any (public) GNS record that Bob has
+in their zone by replacing www with the respective name of the
+record in Bob's zone.
+
+@c themselves? themself?
+Furthermore, if Bob has themselves a (public) delegation to Carol's
+zone under "carol", you can access Carol's records under
+NAME.carol.bob.gnu (where NAME is the name of Carol's record you
+want to access).
+
+@node The Three Local Zones of GNS
+@subsection The Three Local Zones of GNS
+
+Each user GNS has control over three zones. Each of the zones
+has a different purpose. These zones are the
+
+@itemize @bullet
+
+@item master zone,
+@item private zone, and the
+@item shorten zone.
+@end itemize
+
+@node The Master Zone
+@subsection The Master Zone
+
+
+The master zone is your personal TLD. Names within the @code{.gnu}
+namespace are resolved relative to this zone. You can arbitrarily
+add records to this zone and selectively publish those records.
+
+@node The Private Zone
+@subsection The Private Zone
+
+
+The private zone is a subzone (or subdomain in DNS terms) of your
+master zone. It should be used for records that you want to keep
+private. For example @code{bank.private.gnu}. The key idea is that
+you want to keep your private records separate, if just to know
+that those names are not available to other users.
+
+@node The Shorten Zone
+@subsection The Shorten Zone
+
+
+The shorten zone can either be a subzone of the master zone or the
+private zone. It is different from the other zones in that GNS
+will automatically populate this zone with other users' zones based
+on their PSEU records whenever you resolve a name.
+
+For example if you go to
+@code{@uref{http://www.bob.alice.dave.gnu/, www.bob.alice.dave.gnu}},
+GNS will try to import @code{bob} into your shorten zone. Having
+obtained Bob's PKEY from @code{alice.dave.gnu}, GNS will lookup the
+PSEU record for @code{+} in Bob's zone. If it exists and the specified
+pseudonym is not taken, Bob's PKEY will be automatically added under
+that pseudonym (i.e. "bob") into your shorten zone. From then on,
+Bob's webpage will also be available for you as
+@code{@uref{http://www.bob.short.gnu/, www.bob.short.gnu}}.
+This feature is called @b{automatic name shortening} and is supposed to
+keep GNS names as short and memorable as possible.
+
+@node The ZKEY Top Level Domain in GNS
+@subsection The ZKEY Top Level Domain in GNS
+
+
+GNS also provides a secure and globally unique namespace under the .zkey
+top-level domain. A name in the .zkey TLD corresponds to the (printable)
+public key of a zone. Names in the .zkey TLD are then resolved by querying
+the respective zone. The .zkey TLD is expected to be used under rare
+circumstances where globally unique names are required and for
+integration with legacy systems.
+
+@node Resource Records in GNS
+@subsection Resource Records in GNS
+
+
+GNS supports the majority of the DNS records as defined in
+@uref{http://www.ietf.org/rfc/rfc1035.txt, RFC 1035}. Additionally,
+GNS defines some new record types the are unique to the GNS system.
+For example, GNS-specific resource records are used to give petnames
+for zone delegation, revoke zone keys and provide some compatibility
+features.
+
+For some DNS records, GNS does extended processing to increase their
+usefulness in GNS. In particular, GNS introduces special names
+referred to as "zone relative names". Zone relative names are allowed
+in some resource record types (for example, in NS and CNAME records)
+and can also be used in links on webpages. Zone relative names end
+in ".+" which indicates that the name needs to be resolved relative
+to the current authoritative zone. The extended processing of those
+names will expand the ".+" with the correct delegation chain to the
+authoritative zone (replacing ".+" with the name of the location
+where the name was encountered) and hence generate a
+valid @code{.gnu} name.
+
+GNS currently supports the following record types:
+
+@menu
+* NICK::
+* PKEY::
+* BOX::
+* LEHO::
+* VPN::
+* A AAAA and TXT::
+* CNAME::
+* GNS2DNS::
+* SOA SRV PTR and MX::
+@end menu
+
+@node NICK
+@subsubsection NICK
+
+A NICK record is used to give a zone a name. With a NICK record, you can
+essentially specify how you would like to be called. GNS expects this
+record under the name "+" in the zone's database (NAMESTORE); however,
+it will then automatically be copied into each record set, so that
+clients never need to do a separate lookup to discover the NICK record.
+
+@b{Example}@
+
+@example
+Name: +; RRType: NICK; Value: bob
+@end example
+
+@noindent
+This record in Bob's zone will tell other users that this zone wants
+to be referred to as 'bob'. Note that nobody is obliged to call Bob's
+zone 'bob' in their own zones. It can be seen as a
+recommendation ("Please call me 'bob'").
+
+@node PKEY
+@subsubsection PKEY
+
+PKEY records are used to add delegation to other users' zones and
+give those zones a petname.
+
+@b{Example}@
+
+Let Bob's zone be identified by the hash "ABC012". Bob is your friend
+so you want to give them the petname "friend". Then you add the
+following record to your zone:
+
+@example
+Name: friend; RRType: PKEY; Value: ABC012;
+@end example
+
+@noindent
+This will allow you to resolve records in bob's zone
+under "*.friend.gnu".
+
+@node BOX
+@subsubsection BOX
+
+BOX records are there to integrate information from TLSA or
+SRV records under the main label. In DNS, TLSA and SRV records
+use special names of the form @code{_port._proto.(label.)*tld} to
+indicate the port number and protocol (i.e. tcp or udp) for which
+the TLSA or SRV record is valid. This causes various problems, and
+is elegantly solved in GNS by integrating the protocol and port
+numbers together with the respective value into a "BOX" record.
+Note that in the GUI, you do not get to edit BOX records directly
+right now --- the GUI will provide the illusion of directly
+editing the TLSA and SRV records, even though they internally
+are BOXed up.
+
+@node LEHO
+@subsubsection LEHO
+
+The LEgacy HOstname of a server. Some webservers expect a specific
+hostname to provide a service (virtiual hosting). Also SSL
+certificates usually contain DNS names. To provide the expected
+legacy DNS name for a server, the LEHO record can be used.
+To mitigate the just mentioned issues the GNS proxy has to be used.
+The GNS proxy will use the LEHO information to apply the necessary
+transformations.
+
+@node VPN
+@subsubsection VPN
+
+GNS allows easy access to services provided by the GNUnet Virtual Public
+Network. When the GNS resolver encounters a VPN record it will contact
+the VPN service to try and allocate an IPv4/v6 address (if the queries
+record type is an IP address) that can be used to contact the service.
+
+@b{Example}@
+
+I want to provide access to the VPN service "web.gnu." on port 80 on peer
+ABC012:@
+Name: www; RRType: VPN; Value: 80 ABC012 web.gnu.
+
+The peer ABC012 is configured to provide an exit point for the service
+"web.gnu." on port 80 to it's server running locally on port 8080 by
+having the following lines in the @file{gnunet.conf} configuration file:
+
+@example
+[web.gnunet.]
+TCP_REDIRECTS = 80:localhost4:8080
+@end example
+
+@node A AAAA and TXT
+@subsubsection A AAAA and TXT
+
+Those records work in exactly the same fashion as in traditional DNS.
+
+@node CNAME
+@subsubsection CNAME
+
+As specified in RFC 1035 whenever a CNAME is encountered the query
+needs to be restarted with the specified name. In GNS a CNAME
+can either be:
+
+@itemize @bullet
+@item A zone relative name,
+@item A zkey name or
+@item A DNS name (in which case resolution will continue outside
+of GNS with the systems DNS resolver)
+@end itemize
+
+@node GNS2DNS
+@subsubsection GNS2DNS
+
+GNS can delegate authority to a legacy DNS zone. For this, the
+name of the DNS nameserver and the name of the DNS zone are
+specified in a GNS2DNS record.
+
+@b{Example}
+
+@example
+Name: pet; RRType: GNS2DNS; Value: gnunet.org@@a.ns.joker.com
+@end example
+
+@noindent
+Any query to @code{pet.gnu} will then be delegated to the DNS server at
+@code{a.ns.joker.com}. For example,
+@code{@uref{http://www.pet.gnu/, www.pet.gnu}} will result in a DNS query
+for @code{@uref{http://www.gnunet.org/, www.gnunet.org}} to the server
+at @code{a.ns.joker.com}. Delegation to DNS via NS records in GNS can
+be useful if you do not want to start resolution in the DNS root zone
+(due to issues such as censorship or availability).
+
+Note that you would typically want to use a relative name for the
+nameserver, i.e.
+
+@example
+Name: pet; RRType: GNS2DNS; Value: gnunet.org@@ns-joker.+@
+Name: ns-joker; RRType: A; Value: 184.172.157.218
+@end example
+
+@noindent
+This way, you can avoid involving the DNS hierarchy in the resolution of
+@code{a.ns.joker.com}. In the example above, the problem may not be
+obvious as the nameserver for "gnunet.org" is in the ".com" zone.
+However, imagine the nameserver was "ns.gnunet.org". In this case,
+delegating to "ns.gnunet.org" would mean that despite using GNS,
+censorship in the DNS ".org" zone would still be effective.
+
+@node SOA SRV PTR and MX
+@subsubsection SOA SRV PTR and MX
+
+The domain names in those records can, again, be either
+
+@itemize @bullet
+@item A zone relative name,
+@item A zkey name or
+@item A DNS name
+@end itemize
+
+The resolver will expand the zone relative name if possible.
+Note that when using MX records within GNS, the target mail
+server might still refuse to accept e-mails to the resulting
+domain as the name might not match. GNS-enabled mail clients
+should use the ZKEY zone as the destination hostname and
+GNS-enabled mail servers should be configured to accept
+e-mails to the ZKEY-zones of all local users.
+
+@node Using the Virtual Public Network
+@section Using the Virtual Public Network
+
+@menu
+* Setting up an Exit node::
+* Fedora and the Firewall::
+* Setting up VPN node for protocol translation and tunneling::
+@end menu
+
+Using the GNUnet Virtual Public Network (VPN) application you can
+tunnel IP traffic over GNUnet. Moreover, the VPN comes
+with built-in protocol translation and DNS-ALG support, enabling
+IPv4-to-IPv6 protocol translation (in both directions).
+This chapter documents how to use the GNUnet VPN.
+
+The first thing to note about the GNUnet VPN is that it is a public
+network. All participating peers can participate and there is no
+secret key to control access. So unlike common virtual private
+networks, the GNUnet VPN is not useful as a means to provide a
+"private" network abstraction over the Internet. The GNUnet VPN
+is a virtual network in the sense that it is an overlay over the
+Internet, using its own routing mechanisms and can also use an
+internal addressing scheme. The GNUnet VPN is an Internet
+underlay --- TCP/IP applications run on top of it.
+
+The VPN is currently only supported on GNU/Linux systems.
+Support for operating systems that support TUN (such as FreeBSD)
+should be easy to add (or might not even require any coding at
+all --- we just did not test this so far). Support for other
+operating systems would require re-writing the code to create virtual
+network interfaces and to intercept DNS requests.
+
+The VPN does not provide good anonymity. While requests are routed
+over the GNUnet network, other peers can directly see the source
+and destination of each (encapsulated) IP packet. Finally, if you
+use the VPN to access Internet services, the peer sending the
+request to the Internet will be able to observe and even alter
+the IP traffic. We will discuss additional security implications
+of using the VPN later in this chapter.
+
+@node Setting up an Exit node
+@subsection Setting up an Exit node
+
+Any useful operation with the VPN requires the existence of an exit
+node in the GNUnet Peer-to-Peer network. Exit functionality can only
+be enabled on peers that have regular Internet access. If you want
+to play around with the VPN or support the network, we encourage
+you to setup exit nodes. This chapter documents how to setup an
+exit node.
+
+There are four types of exit functions an exit node can provide,
+and using the GNUnet VPN to access the Internet will only work
+nicely if the first three types are provided somewhere in
+the network. The four exit functions are:
+
+@itemize @bullet
+@item DNS: allow other peers to use your DNS resolver
+@item IPv4: allow other peers to access your IPv4 Internet connection
+@item IPv6: allow other peers to access your IPv6 Internet connection
+@item Local service: allow other peers to access a specific TCP or
+UDP service your peer is providing
+@end itemize
+
+By enabling "exit" in gnunet-setup and checking the respective boxes
+in the "exit" tab, you can easily choose which of the above exit
+functions you want to support.
+
+Note, however, that by supporting the first three functions you will
+allow arbitrary other GNUnet users to access the Internet via your
+system. This is somewhat similar to running a Tor exit node. The
+Torproject has a nice article about what to consider if you want
+to do this here. We believe that generally running a DNS exit node
+is completely harmless.
+
+The exit node configuration does currently not allow you to restrict the
+Internet traffic that leaves your system. In particular, you cannot
+exclude SMTP traffic (or block port 25) or limit to HTTP traffic using
+the GNUnet configuration. However, you can use your host firewall to
+restrict outbound connections from the virtual tunnel interface. This
+is highly recommended. In the future, we plan to offer a wider range
+of configuration options for exit nodes.
+
+Note that by running an exit node GNUnet will configure your kernel
+to perform IP-forwarding (for IPv6) and NAT (for IPv4) so that the
+traffic from the virtual interface can be routed to the Internet.
+In order to provide an IPv6-exit, you need to have a subnet routed
+to your host's external network interface and assign a subrange of
+that subnet to the GNUnet exit's TUN interface.
+
+When running a local service, you should make sure that the local
+service is (also) bound to the IP address of your EXIT interface
+(i.e. 169.254.86.1). It will NOT work if your local service is
+just bound to loopback. You may also want to create a "VPN" record
+in your zone of the GNU Name System to make it easy for others to
+access your service via a name instead of just the full service
+descriptor. Note that the identifier you assign the service can
+serve as a passphrase or shared secret, clients connecting to the
+service must somehow learn the service's name. VPN records in the
+GNU Name System can make this easier.
+
+@node Fedora and the Firewall
+@subsection Fedora and the Firewall
+
+
+When using an exit node on Fedora 15, the standard firewall can
+create trouble even when not really exiting the local system!
+For IPv4, the standard rules seem fine. However, for IPv6 the
+standard rules prohibit traffic from the network range of the
+virtual interface created by the exit daemon to the local IPv6
+address of the same interface (which is essentially loopback
+traffic, so you might suspect that a standard firewall would
+leave this traffic alone). However, as somehow for IPv6 the
+traffic is not recognized as originating from the local
+system (and as the connection is not already "established"),
+the firewall drops the traffic. You should still get ICMPv6
+packets back, but that's obviously not very useful.
+
+Possible ways to fix this include disabling the firewall (do you
+have a good reason for having it on?) or disabling the firewall
+at least for the GNUnet exit interface (or the respective
+IPv4/IPv6 address range). The best way to diagnose these kinds
+of problems in general involves setting the firewall to REJECT
+instead of DROP and to watch the traffic using wireshark
+(or tcpdump) to see if ICMP messages are generated when running
+some tests that should work.
+
+@node Setting up VPN node for protocol translation and tunneling
+@subsection Setting up VPN node for protocol translation and tunneling
+
+
+The GNUnet VPN/PT subsystem enables you to tunnel IP traffic over the
+VPN to an exit node, from where it can then be forwarded to the
+Internet. This section documents how to setup VPN/PT on a node.
+Note that you can enable both the VPN and an exit on the same peer.
+In this case, IP traffic from your system may enter your peer's VPN
+and leave your peer's exit. This can be useful as a means to do
+protocol translation. For example, you might have an application that
+supports only IPv4 but needs to access an IPv6-only site. In this case,
+GNUnet would perform 4to6 protocol translation between the VPN (IPv4)
+and the Exit (IPv6). Similarly, 6to4 protocol translation is also
+possible. However, the primary use for GNUnet would be to access
+an Internet service running with an IP version that is not supported
+by your ISP. In this case, your IP traffic would be routed via GNUnet
+to a peer that has access to the Internet with the desired IP version.
+
+Setting up an entry node into the GNUnet VPN primarily requires you
+to enable the "VPN/PT" option in "gnunet-setup". This will launch the
+"gnunet-service-vpn", "gnunet-service-dns" and "gnunet-daemon-pt"
+processes. The "gnunet-service-vpn" will create a virtual interface
+which will be used as the target for your IP traffic that enters the
+VPN. Additionally, a second virtual interface will be created by
+the "gnunet-service-dns" for your DNS traffic. You will then need to
+specify which traffic you want to tunnel over GNUnet. If your ISP only
+provides you with IPv4 or IPv6-access, you may choose to tunnel the
+other IP protocol over the GNUnet VPN. If you do not have an ISP
+(and are connected to other GNUnet peers via WLAN), you can also
+choose to tunnel all IP traffic over GNUnet. This might also provide
+you with some anonymity. After you enable the respective options
+and restart your peer, your Internet traffic should be tunneled
+over the GNUnet VPN.
+
+The GNUnet VPN uses DNS-ALG to hijack your IP traffic. Whenever an
+application resolves a hostname (i.e. 'gnunet.org'), the
+"gnunet-daemon-pt" will instruct the "gnunet-service-dns" to intercept
+the request (possibly route it over GNUnet as well) and replace the
+normal answer with an IP in the range of the VPN's interface.
+"gnunet-daemon-pt" will then tell "gnunet-service-vpn" to forward all
+traffic it receives on the TUN interface via the VPN to the original
+destination.
+
+For applications that do not use DNS, you can also manually create
+such a mapping using the gnunet-vpn command-line tool. Here, you
+specfiy the desired address family of the result (i.e. "-4"), and the
+intended target IP on the Internet ("-i 131.159.74.67") and
+"gnunet-vpn" will tell you which IP address in the range of your
+VPN tunnel was mapped.
+
+@command{gnunet-vpn} can also be used to access "internal" services
+offered by GNUnet nodes. So if you happen to know a peer and a
+service offered by that peer, you can create an IP tunnel to
+that peer by specifying the peer's identity, service name and
+protocol (--tcp or --udp) and you will again receive an IP address
+that will terminate at the respective peer's service.
--- /dev/null
+@node Vocabulary
+@chapter Vocabulary
+
+@menu
+* Words and characters::
+* Technical Assumptions::
+@end menu
+
+@node Words and characters
+@section Words and characters
+
+Throughout this document we use certain words and characters.
+
+@enumerate
+@item
+``@command{#}'' in example code blocks describes commands, ie comments.
+
+@example
+# Do the foobar thing:
+$ make foobar
+@end example
+
+@item
+Dollarsign ``@command{$}'' in example code blocks describes commands you
+execute as unprivileged users.
+
+@example
+$ cd foo; ./configure --example-switch
+@end example
+
+@item
+Backslash ``@command{\}'' describes linebreaks.
+
+@example
+./configure --foo --bar --baz \
+ --short-loop
+@end example
+
+...expands to @code{./configure --foo --bar --baz --short-loop}
+
+@end enumerate
+
+@node Technical Assumptions
+@section Technical Assumptions
+
+@c Is it really assuming Bash (ie Bash extensions of POSIX being used)?
+The shell on GNU systems is assumed to be Bash.
--- /dev/null
+html, body {
+ font-size: 1em;
+ text-align: left;
+ text-decoration: none;
+}
+html { background-color: #e7e7e7; }
+
+body {
+ max-width: 74.92em;
+ margin: 0 auto;
+ padding: .5em 1em 1em 1em;
+ background-color: white;
+ border: .1em solid #c0c0c0;
+}
+
+h1, h2, h3, h4 { color: #333; }
+h5, h6, dt { color: #222; }
+
+
+a h3 {
+ color: #005090;
+}
+
+a[href] { color: #005090; }
+a[href]:visited { color: #100070; }
+a[href]:active, a[href]:hover {
+ color: #100070;
+ text-decoration: none;
+}
+
+.linkrow {
+ margin: 3em 0;
+}
+
+.linkrow {
+ text-align: center;
+}
+
+div.example { padding: .8em 1.2em .4em; }
+pre.example { padding: .8em 1.2em; }
+div.example, pre.example {
+ margin: 1em 0 1em 3% ;
+ -webkit-border-radius: .3em;
+ -moz-border-radius: .3em;
+ border-radius: .3em;
+ border: 1px solid #d4cbb6;
+ background-color: #f2efe4;
+}
+div.example > pre.example {
+ padding: 0 0 .4em;
+ margin: 0;
+ border: none;
+}
+
+
+/* This makes the very long tables of contents in Gnulib and other
+ manuals easier to read. */
+.contents ul, .shortcontents ul { font-weight: bold; }
+.contents ul ul, .shortcontents ul ul { font-weight: normal; }
+.contents ul { list-style: none; }
+
+/* For colored navigation bars (Emacs manual): make the bar extend
+ across the whole width of the page and give it a decent height. */
+.header, .node { margin: 0 -1em; padding: 0 1em; }
+.header p, .node p { line-height: 2em; }
+
+/* For navigation links */
+.node a, .header a { display: inline-block; line-height: 2em; }
+.node a:hover, .header a:hover { background: #f2efe4; }
+
+table.cartouche {
+ border-collapse: collapse;
+ border-color: darkred;
+ border-style: solid;
+ border-width: 3px;
+}
--- /dev/null
+@c The GNU Free Documentation License.
+@center Version 1.3, 3 November 2008
+
+@c This file is intended to be included within another document,
+@c hence no sectioning command or @node.
+
+@display
+Copyright @copyright{} 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
+@uref{http://fsf.org/}
+
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+@end display
+
+@enumerate 0
+@item
+PREAMBLE
+
+The purpose of this License is to make a manual, textbook, or other
+functional and useful document @dfn{free} in the sense of freedom: to
+assure everyone the effective freedom to copy and redistribute it,
+with or without modifying it, either commercially or noncommercially.
+Secondarily, this License preserves for the author and publisher a way
+to get credit for their work, while not being considered responsible
+for modifications made by others.
+
+This License is a kind of ``copyleft'', which means that derivative
+works of the document must themselves be free in the same sense. It
+complements the GNU General Public License, which is a copyleft
+license designed for free software.
+
+We have designed this License in order to use it for manuals for free
+software, because free software needs free documentation: a free
+program should come with manuals providing the same freedoms that the
+software does. But this License is not limited to software manuals;
+it can be used for any textual work, regardless of subject matter or
+whether it is published as a printed book. We recommend this License
+principally for works whose purpose is instruction or reference.
+
+@item
+APPLICABILITY AND DEFINITIONS
+
+This License applies to any manual or other work, in any medium, that
+contains a notice placed by the copyright holder saying it can be
+distributed under the terms of this License. Such a notice grants a
+world-wide, royalty-free license, unlimited in duration, to use that
+work under the conditions stated herein. The ``Document'', below,
+refers to any such manual or work. Any member of the public is a
+licensee, and is addressed as ``you''. You accept the license if you
+copy, modify or distribute the work in a way requiring permission
+under copyright law.
+
+A ``Modified Version'' of the Document means any work containing the
+Document or a portion of it, either copied verbatim, or with
+modifications and/or translated into another language.
+
+A ``Secondary Section'' is a named appendix or a front-matter section
+of the Document that deals exclusively with the relationship of the
+publishers or authors of the Document to the Document's overall
+subject (or to related matters) and contains nothing that could fall
+directly within that overall subject. (Thus, if the Document is in
+part a textbook of mathematics, a Secondary Section may not explain
+any mathematics.) The relationship could be a matter of historical
+connection with the subject or with related matters, or of legal,
+commercial, philosophical, ethical or political position regarding
+them.
+
+The ``Invariant Sections'' are certain Secondary Sections whose titles
+are designated, as being those of Invariant Sections, in the notice
+that says that the Document is released under this License. If a
+section does not fit the above definition of Secondary then it is not
+allowed to be designated as Invariant. The Document may contain zero
+Invariant Sections. If the Document does not identify any Invariant
+Sections then there are none.
+
+The ``Cover Texts'' are certain short passages of text that are listed,
+as Front-Cover Texts or Back-Cover Texts, in the notice that says that
+the Document is released under this License. A Front-Cover Text may
+be at most 5 words, and a Back-Cover Text may be at most 25 words.
+
+A ``Transparent'' copy of the Document means a machine-readable copy,
+represented in a format whose specification is available to the
+general public, that is suitable for revising the document
+straightforwardly with generic text editors or (for images composed of
+pixels) generic paint programs or (for drawings) some widely available
+drawing editor, and that is suitable for input to text formatters or
+for automatic translation to a variety of formats suitable for input
+to text formatters. A copy made in an otherwise Transparent file
+format whose markup, or absence of markup, has been arranged to thwart
+or discourage subsequent modification by readers is not Transparent.
+An image format is not Transparent if used for any substantial amount
+of text. A copy that is not ``Transparent'' is called ``Opaque''.
+
+Examples of suitable formats for Transparent copies include plain
+ASCII without markup, Texinfo input format, La@TeX{} input
+format, SGML or XML using a publicly available
+DTD, and standard-conforming simple HTML,
+PostScript or PDF designed for human modification. Examples
+of transparent image formats include PNG, XCF and
+JPG. Opaque formats include proprietary formats that can be
+read and edited only by proprietary word processors, SGML or
+XML for which the DTD and/or processing tools are
+not generally available, and the machine-generated HTML,
+PostScript or PDF produced by some word processors for
+output purposes only.
+
+The ``Title Page'' means, for a printed book, the title page itself,
+plus such following pages as are needed to hold, legibly, the material
+this License requires to appear in the title page. For works in
+formats which do not have any title page as such, ``Title Page'' means
+the text near the most prominent appearance of the work's title,
+preceding the beginning of the body of the text.
+
+The ``publisher'' means any person or entity that distributes copies
+of the Document to the public.
+
+A section ``Entitled XYZ'' means a named subunit of the Document whose
+title either is precisely XYZ or contains XYZ in parentheses following
+text that translates XYZ in another language. (Here XYZ stands for a
+specific section name mentioned below, such as ``Acknowledgements'',
+``Dedications'', ``Endorsements'', or ``History''.) To ``Preserve the Title''
+of such a section when you modify the Document means that it remains a
+section ``Entitled XYZ'' according to this definition.
+
+The Document may include Warranty Disclaimers next to the notice which
+states that this License applies to the Document. These Warranty
+Disclaimers are considered to be included by reference in this
+License, but only as regards disclaiming warranties: any other
+implication that these Warranty Disclaimers may have is void and has
+no effect on the meaning of this License.
+
+@item
+VERBATIM COPYING
+
+You may copy and distribute the Document in any medium, either
+commercially or noncommercially, provided that this License, the
+copyright notices, and the license notice saying this License applies
+to the Document are reproduced in all copies, and that you add no other
+conditions whatsoever to those of this License. You may not use
+technical measures to obstruct or control the reading or further
+copying of the copies you make or distribute. However, you may accept
+compensation in exchange for copies. If you distribute a large enough
+number of copies you must also follow the conditions in section 3.
+
+You may also lend copies, under the same conditions stated above, and
+you may publicly display copies.
+
+@item
+COPYING IN QUANTITY
+
+If you publish printed copies (or copies in media that commonly have
+printed covers) of the Document, numbering more than 100, and the
+Document's license notice requires Cover Texts, you must enclose the
+copies in covers that carry, clearly and legibly, all these Cover
+Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
+the back cover. Both covers must also clearly and legibly identify
+you as the publisher of these copies. The front cover must present
+the full title with all words of the title equally prominent and
+visible. You may add other material on the covers in addition.
+Copying with changes limited to the covers, as long as they preserve
+the title of the Document and satisfy these conditions, can be treated
+as verbatim copying in other respects.
+
+If the required texts for either cover are too voluminous to fit
+legibly, you should put the first ones listed (as many as fit
+reasonably) on the actual cover, and continue the rest onto adjacent
+pages.
+
+If you publish or distribute Opaque copies of the Document numbering
+more than 100, you must either include a machine-readable Transparent
+copy along with each Opaque copy, or state in or with each Opaque copy
+a computer-network location from which the general network-using
+public has access to download using public-standard network protocols
+a complete Transparent copy of the Document, free of added material.
+If you use the latter option, you must take reasonably prudent steps,
+when you begin distribution of Opaque copies in quantity, to ensure
+that this Transparent copy will remain thus accessible at the stated
+location until at least one year after the last time you distribute an
+Opaque copy (directly or through your agents or retailers) of that
+edition to the public.
+
+It is requested, but not required, that you contact the authors of the
+Document well before redistributing any large number of copies, to give
+them a chance to provide you with an updated version of the Document.
+
+@item
+MODIFICATIONS
+
+You may copy and distribute a Modified Version of the Document under
+the conditions of sections 2 and 3 above, provided that you release
+the Modified Version under precisely this License, with the Modified
+Version filling the role of the Document, thus licensing distribution
+and modification of the Modified Version to whoever possesses a copy
+of it. In addition, you must do these things in the Modified Version:
+
+@enumerate A
+@item
+Use in the Title Page (and on the covers, if any) a title distinct
+from that of the Document, and from those of previous versions
+(which should, if there were any, be listed in the History section
+of the Document). You may use the same title as a previous version
+if the original publisher of that version gives permission.
+
+@item
+List on the Title Page, as authors, one or more persons or entities
+responsible for authorship of the modifications in the Modified
+Version, together with at least five of the principal authors of the
+Document (all of its principal authors, if it has fewer than five),
+unless they release you from this requirement.
+
+@item
+State on the Title page the name of the publisher of the
+Modified Version, as the publisher.
+
+@item
+Preserve all the copyright notices of the Document.
+
+@item
+Add an appropriate copyright notice for your modifications
+adjacent to the other copyright notices.
+
+@item
+Include, immediately after the copyright notices, a license notice
+giving the public permission to use the Modified Version under the
+terms of this License, in the form shown in the Addendum below.
+
+@item
+Preserve in that license notice the full lists of Invariant Sections
+and required Cover Texts given in the Document's license notice.
+
+@item
+Include an unaltered copy of this License.
+
+@item
+Preserve the section Entitled ``History'', Preserve its Title, and add
+to it an item stating at least the title, year, new authors, and
+publisher of the Modified Version as given on the Title Page. If
+there is no section Entitled ``History'' in the Document, create one
+stating the title, year, authors, and publisher of the Document as
+given on its Title Page, then add an item describing the Modified
+Version as stated in the previous sentence.
+
+@item
+Preserve the network location, if any, given in the Document for
+public access to a Transparent copy of the Document, and likewise
+the network locations given in the Document for previous versions
+it was based on. These may be placed in the ``History'' section.
+You may omit a network location for a work that was published at
+least four years before the Document itself, or if the original
+publisher of the version it refers to gives permission.
+
+@item
+For any section Entitled ``Acknowledgements'' or ``Dedications'', Preserve
+the Title of the section, and preserve in the section all the
+substance and tone of each of the contributor acknowledgements and/or
+dedications given therein.
+
+@item
+Preserve all the Invariant Sections of the Document,
+unaltered in their text and in their titles. Section numbers
+or the equivalent are not considered part of the section titles.
+
+@item
+Delete any section Entitled ``Endorsements''. Such a section
+may not be included in the Modified Version.
+
+@item
+Do not retitle any existing section to be Entitled ``Endorsements'' or
+to conflict in title with any Invariant Section.
+
+@item
+Preserve any Warranty Disclaimers.
+@end enumerate
+
+If the Modified Version includes new front-matter sections or
+appendices that qualify as Secondary Sections and contain no material
+copied from the Document, you may at your option designate some or all
+of these sections as invariant. To do this, add their titles to the
+list of Invariant Sections in the Modified Version's license notice.
+These titles must be distinct from any other section titles.
+
+You may add a section Entitled ``Endorsements'', provided it contains
+nothing but endorsements of your Modified Version by various
+parties---for example, statements of peer review or that the text has
+been approved by an organization as the authoritative definition of a
+standard.
+
+You may add a passage of up to five words as a Front-Cover Text, and a
+passage of up to 25 words as a Back-Cover Text, to the end of the list
+of Cover Texts in the Modified Version. Only one passage of
+Front-Cover Text and one of Back-Cover Text may be added by (or
+through arrangements made by) any one entity. If the Document already
+includes a cover text for the same cover, previously added by you or
+by arrangement made by the same entity you are acting on behalf of,
+you may not add another; but you may replace the old one, on explicit
+permission from the previous publisher that added the old one.
+
+The author(s) and publisher(s) of the Document do not by this License
+give permission to use their names for publicity for or to assert or
+imply endorsement of any Modified Version.
+
+@item
+COMBINING DOCUMENTS
+
+You may combine the Document with other documents released under this
+License, under the terms defined in section 4 above for modified
+versions, provided that you include in the combination all of the
+Invariant Sections of all of the original documents, unmodified, and
+list them all as Invariant Sections of your combined work in its
+license notice, and that you preserve all their Warranty Disclaimers.
+
+The combined work need only contain one copy of this License, and
+multiple identical Invariant Sections may be replaced with a single
+copy. If there are multiple Invariant Sections with the same name but
+different contents, make the title of each such section unique by
+adding at the end of it, in parentheses, the name of the original
+author or publisher of that section if known, or else a unique number.
+Make the same adjustment to the section titles in the list of
+Invariant Sections in the license notice of the combined work.
+
+In the combination, you must combine any sections Entitled ``History''
+in the various original documents, forming one section Entitled
+``History''; likewise combine any sections Entitled ``Acknowledgements'',
+and any sections Entitled ``Dedications''. You must delete all
+sections Entitled ``Endorsements.''
+
+@item
+COLLECTIONS OF DOCUMENTS
+
+You may make a collection consisting of the Document and other documents
+released under this License, and replace the individual copies of this
+License in the various documents with a single copy that is included in
+the collection, provided that you follow the rules of this License for
+verbatim copying of each of the documents in all other respects.
+
+You may extract a single document from such a collection, and distribute
+it individually under this License, provided you insert a copy of this
+License into the extracted document, and follow this License in all
+other respects regarding verbatim copying of that document.
+
+@item
+AGGREGATION WITH INDEPENDENT WORKS
+
+A compilation of the Document or its derivatives with other separate
+and independent documents or works, in or on a volume of a storage or
+distribution medium, is called an ``aggregate'' if the copyright
+resulting from the compilation is not used to limit the legal rights
+of the compilation's users beyond what the individual works permit.
+When the Document is included in an aggregate, this License does not
+apply to the other works in the aggregate which are not themselves
+derivative works of the Document.
+
+If the Cover Text requirement of section 3 is applicable to these
+copies of the Document, then if the Document is less than one half of
+the entire aggregate, the Document's Cover Texts may be placed on
+covers that bracket the Document within the aggregate, or the
+electronic equivalent of covers if the Document is in electronic form.
+Otherwise they must appear on printed covers that bracket the whole
+aggregate.
+
+@item
+TRANSLATION
+
+Translation is considered a kind of modification, so you may
+distribute translations of the Document under the terms of section 4.
+Replacing Invariant Sections with translations requires special
+permission from their copyright holders, but you may include
+translations of some or all Invariant Sections in addition to the
+original versions of these Invariant Sections. You may include a
+translation of this License, and all the license notices in the
+Document, and any Warranty Disclaimers, provided that you also include
+the original English version of this License and the original versions
+of those notices and disclaimers. In case of a disagreement between
+the translation and the original version of this License or a notice
+or disclaimer, the original version will prevail.
+
+If a section in the Document is Entitled ``Acknowledgements'',
+``Dedications'', or ``History'', the requirement (section 4) to Preserve
+its Title (section 1) will typically require changing the actual
+title.
+
+@item
+TERMINATION
+
+You may not copy, modify, sublicense, or distribute the Document
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense, or distribute it is void, and
+will automatically terminate your rights under this License.
+
+However, if you cease all violation of this License, then your license
+from a particular copyright holder is reinstated (a) provisionally,
+unless and until the copyright holder explicitly and finally
+terminates your license, and (b) permanently, if the copyright holder
+fails to notify you of the violation by some reasonable means prior to
+60 days after the cessation.
+
+Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, receipt of a copy of some or all of the same material does
+not give you any rights to use it.
+
+@item
+FUTURE REVISIONS OF THIS LICENSE
+
+The Free Software Foundation may publish new, revised versions
+of the GNU Free Documentation License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns. See
+@uref{http://www.gnu.org/copyleft/}.
+
+Each version of the License is given a distinguishing version number.
+If the Document specifies that a particular numbered version of this
+License ``or any later version'' applies to it, you have the option of
+following the terms and conditions either of that specified version or
+of any later version that has been published (not as a draft) by the
+Free Software Foundation. If the Document does not specify a version
+number of this License, you may choose any version ever published (not
+as a draft) by the Free Software Foundation. If the Document
+specifies that a proxy can decide which future versions of this
+License can be used, that proxy's public statement of acceptance of a
+version permanently authorizes you to choose that version for the
+Document.
+
+@item
+RELICENSING
+
+``Massive Multiauthor Collaboration Site'' (or ``MMC Site'') means any
+World Wide Web server that publishes copyrightable works and also
+provides prominent facilities for anybody to edit those works. A
+public wiki that anybody can edit is an example of such a server. A
+``Massive Multiauthor Collaboration'' (or ``MMC'') contained in the
+site means any set of copyrightable works thus published on the MMC
+site.
+
+``CC-BY-SA'' means the Creative Commons Attribution-Share Alike 3.0
+license published by Creative Commons Corporation, a not-for-profit
+corporation with a principal place of business in San Francisco,
+California, as well as future copyleft versions of that license
+published by that same organization.
+
+``Incorporate'' means to publish or republish a Document, in whole or
+in part, as part of another Document.
+
+An MMC is ``eligible for relicensing'' if it is licensed under this
+License, and if all works that were first published under this License
+somewhere other than this MMC, and subsequently incorporated in whole
+or in part into the MMC, (1) had no cover texts or invariant sections,
+and (2) were thus incorporated prior to November 1, 2008.
+
+The operator of an MMC Site may republish an MMC contained in the site
+under CC-BY-SA on the same site at any time before August 1, 2009,
+provided the MMC is eligible for relicensing.
+
+@end enumerate
+
+@page
+@heading ADDENDUM: How to use this License for your documents
+
+To use this License in a document you have written, include a copy of
+the License in the document and put the following copyright and
+license notices just after the title page:
+
+@smallexample
+@group
+ Copyright (C) @var{year} @var{your name}.
+ Permission is granted to copy, distribute and/or modify this document
+ under the terms of the GNU Free Documentation License, Version 1.3
+ or any later version published by the Free Software Foundation;
+ with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
+ Texts. A copy of the license is included in the section entitled ``GNU
+ Free Documentation License''.
+@end group
+@end smallexample
+
+If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
+replace the ``with@dots{}Texts.''@: line with this:
+
+@smallexample
+@group
+ with the Invariant Sections being @var{list their titles}, with
+ the Front-Cover Texts being @var{list}, and with the Back-Cover Texts
+ being @var{list}.
+@end group
+@end smallexample
+
+If you have Invariant Sections without Cover Texts, or some other
+combination of the three, merge those two alternatives to suit the
+situation.
+
+If your document contains nontrivial examples of program code, we
+recommend releasing these examples in parallel under your choice of
+free software license, such as the GNU General Public License,
+to permit their use in free software.
+
+@c Local Variables:
+@c ispell-local-pdict: "ispell-dict"
+@c End:
--- /dev/null
+\input texinfo
+@c %**start of header
+@setfilename gnunet-c-tutorial.info
+@documentencoding UTF-8
+@settitle GNUnet C Tutorial
+@exampleindent 2
+@c %**end of header
+
+@c including 'version.texi' makes makeinfo throw errors.
+@include version2.texi
+
+@copying
+Copyright @copyright{} 2001-2017 GNUnet e.V.
+
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.3 or
+any later version published by the Free Software Foundation; with no
+Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A
+copy of the license is included in the section entitled ``GNU Free
+Documentation License''.
+
+A copy of the license is also available from the Free Software
+Foundation Web site at @url{http://www.gnu.org/licenses/fdl.html}.
+
+Alternately, this document is also available under the General
+Public License, version 3 or later, as published by the Free Software
+Foundation. A copy of the license is included in the section entitled
+``GNU General Public License''.
+
+A copy of the license is also available from the Free Software
+Foundation Web site at @url{http://www.gnu.org/licenses/gpl.html}.
+@end copying
+
+@dircategory Tutorial
+@direntry
+* GNUnet-C-Tutorial: (gnunet-c-tutorial). C Tutorial for GNunet
+@end direntry
+
+
+@titlepage
+@title GNUnet C Tutorial
+@subtitle A Tutorial for GNUnet @value{VERSION} (C version)
+@author The GNUnet Developers
+
+@page
+@vskip 0pt plus 1filll
+
+@insertcopying
+@end titlepage
+
+@contents
+
+@c **** TODO
+@c 1. Update content?
+@c 2. Either reference main documentation or
+@c 3. Merge this into main documentation
+
+@node Top
+@top Introduction
+
+This tutorials explains how to install GNUnet on a
+GNU/Linux system and gives an introduction on how
+GNUnet can be used to develop a Peer-to-Peer application.
+Detailed installation instructions for
+various operating systems and a detailed list of all
+dependencies can be found on our website at
+@uref{https://gnunet.org/installation} and in our
+Reference Documentation (GNUnet Handbook).
+
+Please read this tutorial carefully since every single step is
+important and do not hesitate to contact the GNUnet team if you have
+any questions or problems! Check here how to contact the GNUnet
+team: @uref{https://gnunet.org/contact_information}
+
+@menu
+
+* Installing GNUnet:: Installing GNUnet
+* Introduction to GNUnet Architecture:: Introduction to GNUnet Architecture
+* First Steps with GNUnet:: First Steps with GNUnet
+* Developing Applications:: Developing Applications
+
+@detailmenu
+ --- The Detailed Node Listing ---
+
+Installing GNUnet
+
+* Obtaining a stable version::
+* Installing Build Tool Chain and Dependencies::
+* Obtaining the latest version from Git::
+* Compiling and Installing GNUnet::
+* Common Issues - Check your GNUnet installation::
+
+Introduction to GNUnet Architecture
+
+First Steps with GNUnet
+
+* Configure your peer::
+* Start a peer::
+* Monitor a peer::
+* Starting Two Peers by Hand::
+* Starting Peers Using the Testbed Service::
+
+Developing Applications
+
+* gnunet-ext::
+* Adapting the Template::
+* Writing a Client Application::
+* Writing a Service::
+* Interacting directly with other Peers using the CORE Service::
+* Storing peer-specific data using the PEERSTORE service::
+* Using the DHT::
+* Debugging with gnunet-arm::
+
+@end detailmenu
+@end menu
+
+@node Installing GNUnet
+@chapter Installing GNUnet
+
+First of all you have to install a current version of GNUnet.
+You can download a tarball of a stable version from GNU FTP mirrors
+or obtain the latest development version from our Git repository.
+
+Most of the time you should prefer to download the stable version
+since with the latest development version things can be broken,
+functionality can be changed or tests can fail. You should only use
+the development version if you know that you require a certain
+feature or a certain issue has been fixed since the last release.
+
+@menu
+* Obtaining a stable version::
+* Installing Build Tool Chain and Dependencies::
+* Obtaining the latest version from Git::
+* Compiling and Installing GNUnet::
+* Common Issues - Check your GNUnet installation::
+@end menu
+
+@node Obtaining a stable version
+@section Obtaining a stable version
+
+Download the tarball from
+@indicateurl{https://ftp.gnu.org/gnu/gnunet/gnunet-@value{VERSION}.tar.gz}.
+
+Make sure to download the associated @file{.sig} file and to verify the
+authenticity of the tarball against it, like this:
+
+@example
+$ wget https://ftp.gnu.org/gnu/gnunet/gnunet-@value{VERSION}.tar.gz.sig
+$ gpg --verify-files gnunet-@value{VERSION}.tar.gz.sig
+@end example
+
+@noindent
+If this command fails because you do not have the required public key,
+then you need to run this command to import it:
+
+@example
+$ gpg --keyserver keys.gnupg.net --recv-keys 48426C7E
+@end example
+
+@noindent
+and rerun the @code{gpg --verify-files} command.
+
+Now you can extract the tarball and rename the resulting
+directory to @i{gnunet} which we will be using in the
+remainder of this document.
+
+@example
+$ tar xvzf gnunet-@value{VERSION}.tar.gz
+$ mv gnunet-@value{VERSION} gnunet
+$ cd gnunet
+@end example
+
+@noindent
+However, please note that stable versions can be very outdated.
+As a developer you are @b{strongly} encouraged to use the version
+from @uref{https://gnunet.org/git/, git}.
+
+@node Installing Build Tool Chain and Dependencies
+@section Installing Build Tool Chain and Dependencies
+
+To successfully compile GNUnet you need the tools to build GNUnet and
+the required dependencies. Please have a look at
+@uref{https://gnunet.org/dependencies} for a list of required dependencies
+and @uref{https://gnunet.org/generic_installation} for specific
+instructions for your operating system. Please check the notes at
+the end of the configure process about required dependencies.
+
+For GNUnet bootstrapping support and the http(s) plugin you should
+install @uref{https://gnunet.org/gnurl, libgnurl}.
+For the filesharing service you should install at least one of the
+datastore backends. MySQL, SQlite and PostgreSQL are supported.
+
+@node Obtaining the latest version from Git
+@section Obtaining the latest version from Git
+
+The latest development version can obtained from our Git repository.
+To obtain the code you need Git installed and checkout the repository
+using:
+
+@example
+$ git clone https://gnunet.org/git/gnunet
+@end example
+
+@noindent
+After cloning the repository you have to execute the @file{bootstrap}
+script in the directory:
+
+@example
+$ cd gnunet ; ./bootstrap
+@end example
+
+@noindent
+The remainder of this tutorial assumes that you have the Git branch
+``master'' checked out.
+
+@node Compiling and Installing GNUnet
+@section Compiling and Installing GNUnet
+
+First, you need to install at least libgnupgerror 1.27 and
+libgcrypt 1.7.6.
+
+@example
+$ export GNUPGFTP="https://www.gnupg.org/ftp/gcrypt"
+$ wget $GNUPGFTP/libgpg-error/libgpg-error-1.27.tar.bz2
+$ tar xf libgpg-error-1.27.tar.bz2
+$ cd libgpg-error-1.27
+$ ./configure
+$ sudo make install
+$ cd ..
+@end example
+
+@example
+$ export GNUPGFTP="https://www.gnupg.org/ftp/gcrypt"
+$ wget $GNUPGFTP/libgcrypt/libgcrypt-1.7.6.tar.bz2
+$ tar xf libgcrypt-1.7.6.tar.bz2
+$ cd libgcrypt-1.7.6
+$ ./configure
+$ sudo make install
+$ cd ..
+@end example
+
+@menu
+* Installation::
+@end menu
+
+@node Installation
+@subsection Installation
+Assuming all dependencies are installed, the following commands will
+compile and install GNUnet in your home directory. You can specify the
+directory where GNUnet will be installed by changing the
+@code{--prefix} value when calling @command{./configure}. If
+you do not specifiy a prefix, GNUnet is installed in the directory
+@file{/usr/local}. When developing new applications you may want
+to enable verbose logging by adding @code{--enable-logging=verbose}:
+
+@example
+$ ./configure --prefix=$PREFIX --enable-logging
+$ make
+$ make install
+@end example
+
+@noindent
+After installing GNUnet you have to add your GNUnet installation
+to your path environmental variable. In addition you have to
+create the @file{.config} directory in your home directory
+(unless it already exists) where GNUnet stores its data and an
+empty GNUnet configuration file:
+
+@example
+$ export PATH=$PATH:$PREFIX/bin
+$ echo export PATH=$PREFIX/bin:\\$PATH >> ~/.bashrc
+$ mkdir ~/.config/
+$ touch ~/.config/gnunet.conf
+@end example
+
+@node Common Issues - Check your GNUnet installation
+@section Common Issues - Check your GNUnet installation
+
+You should check your installation to ensure that installing GNUnet
+was successful up to this point. You should be able to access GNUnet's
+binaries and run GNUnet's self check.
+
+@example
+$ which gnunet-arm
+@end example
+
+@noindent
+should return $PREFIX/bin/gnunet-arm. It should be located in your
+GNUnet installation and the output should not be empty.
+If you see an output like:
+
+@example
+$ which gnunet-arm
+@end example
+
+@noindent
+check your PATH variable to ensure GNUnet's @file{bin} directory is
+included.
+
+GNUnet provides tests for all of its subcomponents. Run
+
+@example
+$ make check
+@end example
+
+@noindent
+to execute tests for all components. @command{make check} traverses all
+subdirectories in @file{src}. For every subdirectory you should
+get a message like this:
+
+@example
+make[2]: Entering directory `/home/$USER/gnunet/contrib'
+PASS: test_gnunet_prefix
+=============
+1 test passed
+=============
+@end example
+
+@node Introduction to GNUnet Architecture
+@chapter Introduction to GNUnet Architecture
+
+GNUnet is organized in layers and services. Each service is composed of a
+main service implementation and a client library for other programs to use
+the service's functionality, described by an API.
+@c This approach is shown in
+@c FIXME: enable this once the commented block below works:
+@c figure~\ref fig:service.
+Some services provide an additional command line tool to enable the user
+to interact with the service.
+
+Very often it is other GNUnet services that will use these APIs to build
+the higher layers of GNUnet on top of the lower ones. Each layer expands
+or extends the functionality of the service below (for instance, to build
+a mesh on top of a DHT).
+@c FXIME: See comment above.
+@c See figure ~\ref fig:interaction for an illustration of this approach.
+
+@c ** @image filename[, width[, height[, alttext[, extension]]]]
+@c FIXME: Texlive (?) 20112 makes the assumption that this means
+@c 'images/OBJECTNAME.txt' but later versions of it (2017) use this
+@c syntax as described below.
+@c TODO: Checkout the makedoc script Guile uses.
+
+@image{images/gnunet-tutorial-service,,5in,Service with API and network protocol,.png}
+
+@image{images/gnunet-tutorial-system,,5in,The layered system architecture of GNUnet,.png}
+
+@c \begin{figure}[!h]
+@c \begin{center}
+@c % \begin{subfigure}
+@c \begin{subfigure}[b]{0.3\textwidth}
+@c \centering
+@c \includegraphics[width=\textwidth]{figs/Service.pdf}
+@c \caption{Service with API and network protocol}
+@c \label{fig:service}
+@c \end{subfigure}
+@c ~~~~~~~~~~
+@c \begin{subfigure}[b]{0.3\textwidth}
+@c \centering
+@c \includegraphics[width=\textwidth]{figs/System.pdf}
+@c \caption{Service interaction}
+@c \label{fig:interaction}
+@c \end{subfigure}
+@c \end{center}
+@c \caption{GNUnet's layered system architecture}
+@c \end{figure}
+
+The main service implementation runs as a standalone process in the
+operating system and the client code runs as part of the client program,
+so crashes of a client do not affect the service process or other clients.
+The service and the clients communicate via a message protocol to be
+defined and implemented by the programmer.
+
+@node First Steps with GNUnet
+@chapter First Steps with GNUnet
+
+@menu
+* Configure your peer::
+* Start a peer::
+* Monitor a peer::
+* Starting Two Peers by Hand::
+* Starting Peers Using the Testbed Service::
+@end menu
+
+@node Configure your peer
+@section Configure your peer
+
+First of all we need to configure your peer. Each peer is started with
+a configuration containing settings for GNUnet itself and its services.
+This configuration is based on the default configuration shipped with
+GNUnet and can be modified. The default configuration is located in the
+@file{$PREFIX/share/gnunet/config.d} directory. When starting a peer, you
+can specify a customized configuration using the the @command{-c} command
+line switch when starting the ARM service and all other services. When
+using a modified configuration the default values are loaded and only
+values specified in the configuration file will replace the default
+values.
+
+Since we want to start additional peers later, we need some modifications
+from the default configuration. We need to create a separate service
+home and a file containing our modifications for this peer:
+
+@example
+$ mkdir ~/gnunet1/
+$ touch peer1.conf
+@end example
+
+@noindent
+Now add the following lines to @file{peer1.conf} to use this directory.
+For simplified usage we want to prevent the peer to connect to the GNUnet
+network since this could lead to confusing output. This modifications
+will replace the default settings:
+
+@example
+[PATHS]
+# Use this directory to store GNUnet data
+GNUNET_HOME = ~/gnunet1/
+[hostlist]
+# prevent bootstrapping
+SERVERS =
+@end example
+
+@node Start a peer
+@section Start a peer
+Each GNUnet instance (called peer) has an identity (peer ID) based on a
+cryptographic public private key pair. The peer ID is the printable hash
+of the public key.
+
+GNUnet services are controlled by a master service, the so called
+@dfn{Automatic Restart Manager} (ARM). ARM starts, stops and even
+restarts services automatically or on demand when a client connects.
+You interact with the ARM service using the @command{gnunet-arm} tool.
+GNUnet can then be started with @command{gnunet-arm -s} and stopped with
+@command{gnunet-arm -e}. An additional service not automatically started
+can be started using @command{gnunet-arm -i <service name>} and stopped
+using @command{gnunet-arm -k <servicename>}.
+
+Once you have started your peer, you can use many other GNUnet commands
+to interact with it. For example, you can run:
+
+@example
+$ gnunet-peerinfo -s
+@end example
+
+@noindent
+to obtain the public key of your peer.
+
+You should see an output containing the peer ID similar to:
+
+@example
+I am peer `0PA02UVRKQTS2C .. JL5Q78F6H0B1ACPV1CJI59MEQUMQCC5G'.
+@end example
+
+@node Monitor a peer
+@section Monitor a peer
+
+In this section, we will monitor the behaviour of our peer's DHT
+service with respect to a specific key. First we will start
+GNUnet and then start the DHT service and use the DHT monitor tool
+to monitor the PUT and GET commands we issue ussing the
+@command{gnunet-dht-put} and @command{gnunet-dht-get} commands.
+Using the ``monitor'' line given below, you can observe the behavior
+of your own peer's DHT with respect to the specified KEY:
+
+@example
+# start gnunet with all default services:
+$ gnunet-arm -c ~/peer1.conf -s
+# start DHT service:
+$ gnunet-arm -c ~/peer1.conf -i dht
+$ cd ~/gnunet/src/dht;
+$ ./gnunet-dht-monitor -c ~/peer1.conf -k KEY
+@end example
+
+@noindent
+Now open a separate terminal and change again to
+the @file{gnunet/src/dht} directory:
+
+@example
+$ cd ~/gnunet/src/dht
+# put VALUE under KEY in the DHT:
+$ ./gnunet-dht-put -c ~/peer1.conf -k KEY -d VALUE
+# get key KEY from the DHT:
+$ ./gnunet/src/dht/gnunet-dht-get -c ~/peer1.conf -k KEY
+# print statistics about current GNUnet state:
+$ gnunet-statistics -c ~/peer1.conf
+# print statistics about DHT service:
+$ gnunet-statistics -c ~/peer1.conf -s dht
+@end example
+
+@node Starting Two Peers by Hand
+@section Starting Two Peers by Hand
+
+This section describes how to start two peers on the same machine by hand.
+The process is rather painful, but the description is somewhat
+instructive. In practice, you might prefer the automated method
+(@pxref{Starting Peers Using the Testbed Service}).
+
+@menu
+* Setup a second peer::
+* Start the second peer and connect the peers::
+* How to connect manually::
+@end menu
+
+@node Setup a second peer
+@subsection Setup a second peer
+We will now start a second peer on your machine.
+For the second peer, you will need to manually create a modified
+configuration file to avoid conflicts with ports and directories.
+A peers configuration file is by default located
+in @file{~/.gnunet/gnunet.conf}. This file is typically very short
+or even empty as only the differences to the defaults need to be
+specified. The defaults are located in many files in the
+@file{$PREFIX/share/gnunet/config.d} directory.
+
+To configure the second peer, use the files
+@file{$PREFIX/share/gnunet/config.d} as a template for your main
+configuration file:
+
+@example
+$ cat $PREFIX/share/gnunet/config.d/*.conf > peer2.conf
+@end example
+
+@noindent
+Now you have to edit @file{peer2.conf} and change:
+
+@itemize
+@item @code{GNUNET\_TEST\_HOME} under @code{PATHS}
+@item Every (uncommented) value for ``@code{PORT}'' (add 10000) in any
+section (the option may be commented out if @code{PORT} is
+prefixed by "\#", in this case, UNIX domain sockets are used
+and the PORT option does not need to be touched)
+@item Every value for ``@code{UNIXPATH}'' in any section
+(e.g. by adding a "-p2" suffix)
+@end itemize
+
+to a fresh, unique value. Make sure that the PORT numbers stay
+below 65536. From now on, whenever you interact with the second peer,
+you need to specify @command{-c peer2.conf} as an additional
+command line argument.
+
+Now, generate the 2nd peer's private key:
+
+@example
+$ gnunet-peerinfo -s -c peer2.conf
+@end example
+
+@noindent
+This may take a while, generate entropy using your keyboard or mouse
+as needed. Also, make sure the output is different from the
+gnunet-peerinfo output for the first peer (otherwise you made an
+error in the configuration).
+
+@node Start the second peer and connect the peers
+@subsection Start the second peer and connect the peers
+
+Then, you can start a second peer using:
+
+@example
+$ gnunet-arm -c peer2.conf -s
+$ gnunet-arm -c peer2.conf -i dht
+$ ~/gnunet/src/dht/gnunet-dht-put -c peer2.conf -k KEY -d VALUE
+$ ~/gnunet/src/dht/gnunet-dht-get -c peer2.conf -k KEY
+@end example
+
+If you want the two peers to connect, you have multiple options:
+
+@itemize
+@item UDP neighbour discovery (automatic)
+@item Setup a bootstrap server
+@item Connect manually
+@end itemize
+
+To setup peer 1 as bootstrapping server change the configuration of
+the first one to be a hostlist server by adding the following lines to
+@file{peer1.conf} to enable bootstrapping server:
+
+@example
+[hostlist]
+OPTIONS = -p
+@end example
+
+@noindent
+Then change @file{peer2.conf} and replace the ``@code{SERVERS}''
+line in the ``@code{[hostlist]}'' section with
+``@code{http://localhost:8080/}''. Restart both peers using:
+
+@example
+# stop first peer
+$ gnunet-arm -c peer1.conf -e
+# start first peer
+$ gnunet-arm -c peer1.conf -s
+# start second peer
+$ gnunet-arm -c peer2.conf -s
+@end example
+
+@noindent
+Note that if you start your peers without changing these settings, they
+will use the ``global'' hostlist servers of the GNUnet P2P network and
+likely connect to those peers. At that point, debugging might become
+tricky as you're going to be connected to many more peers and would
+likely observe traffic and behaviors that are not explicitly controlled
+by you.
+
+@node How to connect manually
+@subsection How to connect manually
+
+If you want to use the @code{peerinfo} tool to connect your
+peers, you should:
+
+@itemize
+@item Set @code{FORCESTART = NO} in section @code{hostlist}
+(to not connect to the global GNUnet)
+@item Start both peers running @command{gnunet-arm -c peer1.conf -s}
+and @command{gnunet-arm -c peer2.conf -s}
+@item Get @code{HELLO} message of the first peer running
+@command{gnunet-peerinfo -c peer1.conf -g}
+@item Give the output to the second peer by running
+@command{gnunet-peerinfo -c peer2.conf -p '<output>'}
+@end itemize
+
+Check that they are connected using @command{gnunet-core -c peer1.conf},
+which should give you the other peer's peer identity:
+
+@example
+$ gnunet-core -c peer1.conf
+Peer `9TVUCS8P5A7ILLBGO6 [...shortened...] 1KNBJ4NGCHP3JPVULDG'
+@end example
+
+@node Starting Peers Using the Testbed Service
+@section Starting Peers Using the Testbed Service
+@c \label{sec:testbed}
+
+GNUnet's testbed service is used for testing scenarios where
+a number of peers are to be started. The testbed can manage peers
+on a single host or on multiple hosts in a distributed fashion.
+On a single affordable computer, it should be possible to run
+around tens of peers without drastically increasing the load on the
+system.
+
+The testbed service can be access through its API
+@file{include/gnunet\_testbed\_service.h}. The API provides many
+routines for managing a group of peers. It also provides a helper
+function @code{GNUNET\_TESTBED\_test\_run()} to quickly setup a
+minimalistic testing environment on a single host.
+
+This function takes a configuration file which will be used as a
+template configuration for the peers. The testbed takes care of
+modifying relevant options in the peers' configuration such as
+@code{SERVICEHOME}, @code{PORT}, @code{UNIXPATH} to unique values
+so that peers run without running into conflicts. It also checks
+and assigns the ports in configurations only if they are free.
+
+Additionally, the testbed service also reads its options from the
+same configuration file. Various available options and details
+about them can be found in the testbed default configuration file
+@file{src/testbed/testbed.conf}.
+
+With the testbed API, a sample test case can be structured as follows:
+
+@example
+@verbatiminclude testbed_test.c
+@end example
+
+@noindent
+The source code for the above listing can be found at
+@uref{https://gnunet.org/git/gnunet.git/tree/doc/testbed_test.c}
+or in the @file{doc/} folder of your repository check-out.
+After installing GNUnet, the above source code can be compiled as:
+
+@example
+$ export CPPFLAGS="-I/path/to/gnunet/headers"
+$ export LDFLAGS="-L/path/to/gnunet/libraries"
+$ gcc $CPPFLAGS $LDFLAGS -o testbed-test testbed_test.c \
+ -lgnunettestbed -lgnunetdht -lgnunetutil
+# Generate (empty) configuration
+$ touch template.conf
+# run it (press CTRL-C to stop)
+$ ./testbed-test
+@end example
+
+@noindent
+The @code{CPPFLAGS} and @code{LDFLAGS} are necessary if GNUnet
+is installed into a different directory other than @file{/usr/local}.
+
+All of testbed API's peer management functions treat management
+actions as operations and return operation handles. It is expected
+that the operations begin immediately, but they may get delayed (to
+balance out load on the system). The program using the API then has
+to take care of marking the operation as ``done'' so that its
+associated resources can be freed immediately and other waiting
+operations can be executed. Operations will be canceled if they are
+marked as ``done'' before their completion.
+
+An operation is treated as completed when it succeeds or fails.
+Completion of an operation is either conveyed as events through
+@i{controller event callback} or through respective operation
+completion callbacks. In functions which support completion
+notification through both controller event callback and operation
+completion callback, first the controller event callback will be
+called. If the operation is not marked as done in that callback
+or if the callback is given as NULL when creating the operation,
+the operation completion callback will be called. The API
+documentation shows which event are to be expected in the
+controller event notifications. It also documents any exceptional
+behaviour.
+
+Once the peers are started, test cases often need to connect
+some of the peers' services. Normally, opening a connect to
+a peer's service requires the peer's configuration. While using
+testbed, the testbed automatically generates per-peer configuration.
+Accessing those configurations directly through file system is
+discouraged as their locations are dynamically created and will be
+different among various runs of testbed. To make access to these
+configurations easy, testbed API provides the function
+@code{GNUNET\_TESTBED\_service\_connect()}. This function fetches
+the configuration of a given peer and calls the @i{Connect Adapter}.
+In the example code, it is the @code{dht\_ca}. A connect adapter is
+expected to open the connection to the needed service by using the
+provided configuration and return the created service connection handle.
+Successful connection to the needed service is signaled through
+@code{service\_connect\_comp\_cb}.
+
+A dual to connect adapter is the @i{Disconnect Adapter}. This callback
+is called after the connect adapter has been called when the operation
+from @code{GNUNET\_TESTBED\_service\_connect()} is marked as ``done''.
+It has to disconnect from the service with the provided service
+handle (@code{op\_result}).
+
+Exercise: Find out how many peers you can run on your system.
+
+Exercise: Find out how to create a 2D torus topology by changing the
+options in the configuration file.
+See @uref{https://gnunet.org/supported-topologies}, then use the
+DHT API to store and retrieve values in the network.
+
+@node Developing Applications
+@chapter Developing Applications
+
+@menu
+* gnunet-ext::
+* Adapting the Template::
+* Writing a Client Application::
+* Writing a Service::
+* Interacting directly with other Peers using the CORE Service::
+* Storing peer-specific data using the PEERSTORE service::
+* Using the DHT::
+* Debugging with gnunet-arm::
+@end menu
+
+@node gnunet-ext
+@section gnunet-ext
+To develop a new peer-to-peer application or to extend GNUnet we provide
+a template build system for writing GNUnet extensions in C. It can be
+obtained as follows:
+
+@example
+$ git clone https://gnunet.org/git/gnunet-ext
+$ cd gnunet-ext/
+$ ./bootstrap
+$ ./configure --prefix=$PREFIX --with-gnunet=$PREFIX
+$ make
+$ make install
+$ make check
+@end example
+
+@noindent
+The GNUnet ext template includes examples and a working buildsystem
+for a new GNUnet service. A common GNUnet service consists of the
+following parts which will be discussed in detail in the remainder
+of this document. The functionality of a GNUnet service is implemented in:
+
+@itemize
+@item the GNUnet service (gnunet-ext/src/ext/gnunet-service-ext.c)
+@item the client API (gnunet-ext/src/ext/ext_api.c)
+@item the client application using the service API
+(gnunet-ext/src/ext/gnunet-ext.c)
+@end itemize
+
+The interfaces for these entities are defined in:
+
+@itemize
+@item client API interface (gnunet-ext/src/ext/ext.h)
+@item the service interface (gnunet-ext/src/include/gnunet_service_SERVICE.h)
+@item the P2P protocol (gnunet-ext/src/include/gnunet_protocols_ext.h)
+@end itemize
+
+
+In addition the ext systems provides:
+
+@itemize
+@item a test testing the API (gnunet-ext/src/ext/test_ext_api.c)
+@item a configuration template for the service
+(gnunet-ext/src/ext/ext.conf.in)
+@end itemize
+
+@node Adapting the Template
+@section Adapting the Template
+
+The first step for writing any extension with a new service is to
+ensure that the @file{ext.conf.in} file contains entries for the
+@code{UNIXPATH}, @code{PORT} and @code{BINARY} for the service in a
+section named after the service.
+
+If you want to adapt the template rename the @file{ext.conf.in} to
+match your services name, you have to modify the @code{AC\_OUTPUT}
+section in @file{configure.ac} in the @file{gnunet-ext} root.
+
+@node Writing a Client Application
+@section Writing a Client Application
+
+When writing any client application (for example, a command-line
+tool), the basic structure is to start with the
+@code{GNUNET\_PROGRAM\_run} function. This function will parse
+command-line options, setup the scheduler and then invoke the
+@code{run} function (with the remaining non-option arguments)
+and a handle to the parsed configuration (and the configuration
+file name that was used, which is typically not needed):
+
+@example
+@verbatiminclude tutorial-examples/001.c
+@end example
+
+@menu
+* Handling command-line options::
+* Writing a Client Library::
+* Writing a user interface::
+@end menu
+
+@node Handling command-line options
+@subsection Handling command-line options
+
+Options can then be added easily by adding global variables and
+expanding the @code{options} array. For example, the following would
+add a string-option and a binary flag (defaulting to @code{NULL} and
+@code{GNUNET\_NO} respectively):
+
+@example
+@verbatiminclude tutorial-examples/002.c
+@end example
+
+Issues such as displaying some helpful text describing options using
+the @code{--help} argument and error handling are taken care of when
+using this approach. Other @code{GNUNET\_GETOPT\_}-functions can be used
+to obtain integer value options, increment counters, etc. You can
+even write custom option parsers for special circumstances not covered
+by the available handlers. To check if an argument was specified by the
+user you initialize the variable with a specific value (e.g. NULL for
+a string and GNUNET\_SYSERR for a integer) and check after parsing
+happened if the values were modified.
+
+Inside the @code{run} method, the program would perform the
+application-specific logic, which typically involves initializing and
+using some client library to interact with the service. The client
+library is supposed to implement the IPC whereas the service provides
+more persistent P2P functions.
+
+Exercise: Add a few command-line options and print them inside
+of @code{run}. What happens if the user gives invalid arguments?
+
+@node Writing a Client Library
+@subsection Writing a Client Library
+
+The first and most important step in writing a client library is to
+decide on an API for the library. Typical API calls include
+connecting to the service, performing application-specific requests
+and cleaning up. Many examples for such service APIs can be found
+in the @file{gnunet/src/include/gnunet\_*\_service.h} files.
+
+Then, a client-service protocol needs to be designed. This typically
+involves defining various message formats in a header that will be
+included by both the service and the client library (but is otherwise
+not shared and hence located within the service's directory and not
+installed by @command{make install}). Each message must start with a
+@code{struct GNUNET\_MessageHeader} and must be shorter than 64k. By
+convention, all fields in IPC (and P2P) messages must be in big-endian
+format (and thus should be read using @code{ntohl} and similar
+functions and written using @code{htonl} and similar functions).
+Unique message types must be defined for each message struct in the
+@file{gnunet\_protocols.h} header (or an extension-specific include
+file).
+
+@menu
+* Connecting to the Service::
+* Sending messages::
+* Receiving Replies from the Service::
+@end menu
+
+@node Connecting to the Service
+@subsubsection Connecting to the Service
+
+Before a client library can implement the application-specific protocol
+with the service, a connection must be created:
+
+@example
+@verbatiminclude tutorial-examples/003.c
+@end example
+
+@noindent
+As a result a @code{GNUNET\_MQ\_Handle} is returned
+which can to used henceforth to transmit messages to the service.
+The complete MQ API can be found in @file{gnunet\_mq\_lib.h}.
+The @code{hanlders} array in the example above is incomplete.
+Here is where you will define which messages you expect to
+receive from the service, and which functions handle them.
+The @code{error\_cb} is a function that is to be called whenever
+there are errors communicating with the service.
+
+@node Sending messages
+@subsubsection Sending messages
+
+In GNUnet, messages are always sent beginning with a
+@code{struct GNUNET\_MessageHeader} in big endian format.
+This header defines the size and the type of the
+message, the payload follows after this header.
+
+@example
+@verbatiminclude tutorial-examples/004.c
+@end example
+
+@noindent
+Existing message types are defined in @file{gnunet\_protocols.h}.
+A common way to create a message is with an envelope:
+
+@example
+@verbatiminclude tutorial-examples/005.c
+@end example
+
+@noindent
+Exercise: Define a message struct that includes a 32-bit
+unsigned integer in addition to the standard GNUnet MessageHeader.
+Add a C struct and define a fresh protocol number for your message.
+Protocol numbers in gnunet-ext are defined
+in @file{gnunet-ext/src/include/gnunet_protocols_ext.h}
+
+Exercise: Find out how you can determine the number of messages
+in a message queue.
+
+Exercise: Find out how you can determine when a message you
+have queued was actually transmitted.
+
+Exercise: Define a helper function to transmit a 32-bit
+unsigned integer (as payload) to a service using some given client
+handle.
+
+@node Receiving Replies from the Service
+@subsubsection Receiving Replies from the Service
+
+Clients can receive messages from the service using the handlers
+specified in the @code{handlers} array we specified when connecting
+to the service. Entries in the the array are usually created using
+one of two macros, depending on whether the message is fixed size
+or variable size. Variable size messages are managed using two
+callbacks, one to check that the message is well-formed, the other
+to actually process the message. Fixed size messages are fully
+checked by the MQ-logic, and thus only need to provide the handler
+to process the message. Note that the prefixes @code{check\_}
+and @code{handle\_} are mandatory.
+
+@example
+@verbatiminclude tutorial-examples/006.c
+@end example
+
+@noindent
+Exercise: Expand your helper function to receive a response message
+(for example, containing just the @code{struct GNUnet MessageHeader}
+without any payload). Upon receiving the service's response, you
+should call a callback provided to your helper function's API.
+
+Exercise: Figure out where you can pass values to the
+closures (@code{cls}).
+
+@node Writing a user interface
+@subsection Writing a user interface
+
+Given a client library, all it takes to access a service now is to
+combine calls to the client library with parsing command-line
+options.
+
+Exercise: Call your client API from your @code{run()} method in your
+client application to send a request to the service. For example,
+send a 32-bit integer value based on a number given at the
+command-line to the service.
+
+@node Writing a Service
+@section Writing a Service
+
+Before you can test the client you've written so far, you'll
+need to also implement the corresponding service.
+
+@menu
+* Code Placement::
+* Starting a Service::
+@end menu
+
+@node Code Placement
+@subsection Code Placement
+
+New services are placed in their own subdirectory under
+@file{gnunet/src}. This subdirectory should contain the API
+implementation file @file{SERVICE\_api.c}, the description of
+the client-service protocol @file{SERVICE.h} and P2P protocol
+@file{SERVICE\_protocol.h}, the implementation of the service itself
+@file{gnunet-service-SERVICE.h} and several files for tests,
+including test code and configuration files.
+
+@node Starting a Service
+@subsection Starting a Service
+
+The key API definition for creating a service is the
+@code{GNUNET\_SERVICE\_MAIN} macro:
+
+@example
+@verbatiminclude tutorial-examples/007.c
+@end example
+
+@noindent
+In addition to the service name and flags, the macro takes three
+functions, typically called @code{run}, @code{client\_connect\_cb} and
+@code{client\_disconnect\_cb} as well as an array of message handlers
+that will be called for incoming messages from clients.
+
+A minimal version of the three central service funtions would look
+like this:
+
+@example
+@verbatiminclude tutorial-examples/008.c
+@end example
+
+@noindent
+Exercise: Write a stub service that processes no messages at all
+in your code. Create a default configuration for it, integrate it
+with the build system and start the service from
+@command{gnunet-service-arm} using @command{gnunet-arm -i NAME}.
+
+Exercise: Figure out how to set the closure (@code{cls}) for handlers
+of a service.
+
+Exercise: Figure out how to send messages from the service back to the
+client.
+
+Each handler function in the service @b{must} eventually (possibly in some
+asynchronous continuation) call
+@code{GNUNET\_SERVICE\_client\_continue()}. Only after this call
+additional messages from the same client may
+be processed. This way, the service can throttle processing messages
+from the same client.
+
+Exercise: Change the service to ``handle'' the message from your
+client (for now, by printing a message). What happens if you
+forget to call @code{GNUNET\_SERVICE\_client\_continue()}?
+
+@node Interacting directly with other Peers using the CORE Service
+@section Interacting directly with other Peers using the CORE Service
+
+FIXME: This section still needs to be updated to the lastest API!
+
+One of the most important services in GNUnet is the @code{CORE} service
+managing connections between peers and handling encryption between peers.
+
+One of the first things any service that extends the P2P protocol
+typically does is connect to the @code{CORE} service using:
+
+@example
+@verbatiminclude tutorial-examples/009.c
+@end example
+
+@menu
+* New P2P connections::
+* Receiving P2P Messages::
+* Sending P2P Messages::
+* End of P2P connections::
+@end menu
+
+@node New P2P connections
+@subsection New P2P connections
+
+Before any traffic with a different peer can be exchanged, the peer must
+be known to the service. This is notified by the @code{CORE}
+@code{connects} callback, which communicates the identity of the new
+peer to the service:
+
+@example
+@verbatiminclude tutorial-examples/010.c
+@end example
+
+@noindent
+Note that whatever you return from @code{connects} is given as the
+@i{cls} argument to the message handlers for messages from
+the respective peer.
+
+Exercise: Create a service that connects to the @code{CORE}. Then
+start (and connect) two peers and print a message once your connect
+callback is invoked.
+
+@node Receiving P2P Messages
+@subsection Receiving P2P Messages
+
+To receive messages from @code{CORE}, you pass the desired
+@i{handlers} to the @code{GNUNET\_CORE\_connect()} function,
+just as we showed for services.
+
+It is your responsibility to process messages fast enough or
+to implement flow control. If an application does not process
+CORE messages fast enough, CORE will randomly drop messages
+to not keep a very long queue in memory.
+
+Exercise: Start one peer with a new service that has a message
+handler and start a second peer that only has your ``old'' service
+without message handlers. Which ``connect'' handlers are invoked when
+the two peers are connected? Why?
+
+@node Sending P2P Messages
+@subsection Sending P2P Messages
+
+You can transmit messages to other peers using the @i{mq} you were
+given during the @code{connect} callback. Note that the @i{mq}
+automatically is released upon @code{disconnect} and that you must
+not use it afterwards.
+
+It is your responsibility to not over-fill the message queue, GNUnet
+will send the messages roughly in the order given as soon as possible.
+
+Exercise: Write a service that upon connect sends messages as
+fast as possible to the other peer (the other peer should run a
+service that ``processes'' those messages). How fast is the
+transmission? Count using the STATISTICS service on both ends. Are
+messages lost? How can you transmit messages faster? What happens if
+you stop the peer that is receiving your messages?
+
+@node End of P2P connections
+@subsection End of P2P connections
+
+If a message handler returns @code{GNUNET\_SYSERR}, the remote
+peer shuts down or there is an unrecoverable network
+disconnection, CORE notifies the service that the peer disconnected.
+After this notification no more messages will be received from the
+peer and the service is no longer allowed to send messages to the peer.
+The disconnect callback looks like the following:
+
+@example
+@verbatiminclude tutorial-examples/011.c
+@end example
+
+@noindent
+Exercise: Fix your service to handle peer disconnects.
+
+@node Storing peer-specific data using the PEERSTORE service
+@section Storing peer-specific data using the PEERSTORE service
+
+GNUnet's PEERSTORE service offers a persistorage for arbitrary
+peer-specific data. Other GNUnet services can use the PEERSTORE
+to store, retrieve and monitor data records. Each data record
+stored with PEERSTORE contains the following fields:
+
+@itemize
+@item subsystem: Name of the subsystem responsible for the record.
+@item peerid: Identity of the peer this record is related to.
+@item key: a key string identifying the record.
+@item value: binary record value.
+@item expiry: record expiry date.
+@end itemize
+
+The first step is to start a connection to the PEERSTORE service:
+@example
+@verbatiminclude tutorial-examples/012.c
+@end example
+
+The service handle @code{peerstore_handle} will be needed for
+all subsequent PEERSTORE operations.
+
+@menu
+* Storing records::
+* Retrieving records::
+* Monitoring records::
+* Disconnecting from PEERSTORE::
+@end menu
+
+@node Storing records
+@subsection Storing records
+
+To store a new record, use the following function:
+
+@example
+@verbatiminclude tutorial-examples/013.c
+@end example
+
+@noindent
+The @code{options} parameter can either be
+@code{GNUNET_PEERSTORE_STOREOPTION_MULTIPLE} which means that multiple
+values can be stored under the same key combination
+(subsystem, peerid, key), or @code{GNUNET_PEERSTORE_STOREOPTION_REPLACE}
+which means that PEERSTORE will replace any existing values under the
+given key combination (subsystem, peerid, key) with the new given value.
+
+The continuation function @code{cont} will be called after the store
+request is successfully sent to the PEERSTORE service. This does not
+guarantee that the record is successfully stored, only that it was
+received by the service.
+
+The @code{GNUNET_PEERSTORE_store} function returns a handle to the store
+operation. This handle can be used to cancel the store operation only
+before the continuation function is called:
+
+@example
+@verbatiminclude tutorial-examples/013.1.c
+@end example
+
+@node Retrieving records
+@subsection Retrieving records
+
+To retrieve stored records, use the following function:
+
+@example
+@verbatiminclude tutorial-examples/014.c
+@end example
+
+@noindent
+The values of @code{peer} and @code{key} can be @code{NULL}. This
+allows the iteration over values stored under any of the following
+key combinations:
+
+@itemize
+@item (subsystem)
+@item (subsystem, peerid)
+@item (subsystem, key)
+@item (subsystem, peerid, key)
+@end itemize
+
+The @code{callback} function will be called once with each retrieved
+record and once more with a @code{NULL} record to signal the end of
+results.
+
+The @code{GNUNET_PEERSTORE_iterate} function returns a handle to the
+iterate operation. This handle can be used to cancel the iterate
+operation only before the callback function is called with a
+@code{NULL} record.
+
+@node Monitoring records
+@subsection Monitoring records
+
+PEERSTORE offers the functionality of monitoring for new records
+stored under a specific key combination (subsystem, peerid, key).
+To start the monitoring, use the following function:
+
+@example
+@verbatiminclude tutorial-examples/015.c
+@end example
+
+@noindent
+Whenever a new record is stored under the given key combination,
+the @code{callback} function will be called with this new
+record. This will continue until the connection to the PEERSTORE
+service is broken or the watch operation is canceled:
+
+@example
+@verbatiminclude tutorial-examples/016.c
+@end example
+
+@node Disconnecting from PEERSTORE
+@subsection Disconnecting from PEERSTORE
+
+When the connection to the PEERSTORE service is no longer needed,
+disconnect using the following function:
+
+@example
+@verbatiminclude tutorial-examples/017.c
+@end example
+
+@noindent
+If the @code{sync_first} flag is set to @code{GNUNET_YES},
+the API will delay the disconnection until all store requests
+are received by the PEERSTORE service. Otherwise, it will
+disconnect immediately.
+
+@node Using the DHT
+@section Using the DHT
+
+The DHT allows to store data so other peers in the P2P network can
+access it and retrieve data stored by any peers in the network.
+This section will explain how to use the DHT. Of course, the first
+thing to do is to connect to the DHT service:
+
+@example
+@verbatiminclude tutorial-examples/018.c
+@end example
+
+@noindent
+The second parameter indicates how many requests in parallel to expect.
+It is not a hard limit, but a good approximation will make the DHT more
+efficient.
+
+@menu
+* Storing data in the DHT::
+* Obtaining data from the DHT::
+* Implementing a block plugin::
+* Monitoring the DHT::
+@end menu
+
+@node Storing data in the DHT
+@subsection Storing data in the DHT
+Since the DHT is a dynamic environment (peers join and leave frequently)
+the data that we put in the DHT does not stay there indefinitely. It is
+important to ``refresh'' the data periodically by simply storing it
+again, in order to make sure other peers can access it.
+
+The put API call offers a callback to signal that the PUT request has been
+sent. This does not guarantee that the data is accessible to others peers,
+or even that is has been stored, only that the service has requested to
+a neighboring peer the retransmission of the PUT request towards its final
+destination. Currently there is no feedback about whether or not the data
+has been sucessfully stored or where it has been stored. In order to
+improve the availablilty of the data and to compensate for possible
+errors, peers leaving and other unfavorable events, just make several
+PUT requests!
+
+@example
+@verbatiminclude tutorial-examples/019.c
+@end example
+
+@noindent
+Exercise: Store a value in the DHT periodically to make sure it
+is available over time. You might consider using the function
+@code{GNUNET\_SCHEDULER\_add\_delayed} and call
+@code{GNUNET\_DHT\_put} from inside a helper function.
+
+@node Obtaining data from the DHT
+@subsection Obtaining data from the DHT
+
+As we saw in the previous example, the DHT works in an asynchronous mode.
+Each request to the DHT is executed ``in the background'' and the API
+calls return immediately. In order to receive results from the DHT, the
+API provides a callback. Once started, the request runs in the service,
+the service will try to get as many results as possible (filtering out
+duplicates) until the timeout expires or we explicitly stop the request.
+It is possible to give a ``forever'' timeout with
+@code{GNUNET\_TIME\_UNIT\_FOREVER\_REL}.
+
+If we give a route option @code{GNUNET\_DHT\_RO\_RECORD\_ROUTE}
+the callback will get a list of all the peers the data has travelled,
+both on the PUT path and on the GET path.
+
+@example
+@verbatiminclude tutorial-examples/020.c
+@end example
+
+@noindent
+Exercise: Store a value in the DHT and after a while retrieve it.
+Show the IDs of all the peers the requests have gone through.
+In order to convert a peer ID to a string, use the function
+@code{GNUNET\_i2s}. Pay attention to the route option parameters
+in both calls!
+
+@node Implementing a block plugin
+@subsection Implementing a block plugin
+
+In order to store data in the DHT, it is necessary to provide a block
+plugin. The DHT uses the block plugin to ensure that only well-formed
+requests and replies are transmitted over the network.
+
+The block plugin should be put in a file @file{plugin\_block\_SERVICE.c}
+in the service's respective directory. The
+mandatory functions that need to be implemented for a block plugin are
+described in the following sections.
+
+@menu
+* Validating requests and replies::
+* Deriving a key from a reply::
+* Initialization of the plugin::
+* Shutdown of the plugin::
+* Integration of the plugin with the build system::
+@end menu
+
+@node Validating requests and replies
+@subsubsection Validating requests and replies
+
+The evaluate function should validate a reply or a request. It returns
+a @code{GNUNET\_BLOCK\_EvaluationResult}, which is an enumeration. All
+possible answers are in @file{gnunet\_block\_lib.h}. The function will
+be called with a @code{reply\_block} argument of @code{NULL} for
+requests. Note that depending on how @code{evaluate} is called, only
+some of the possible return values are valid. The specific meaning of
+the @code{xquery} argument is application-specific. Applications that
+do not use an extended query should check that the @code{xquery\_size}
+is zero. The block group is typically used to filter duplicate
+replies.
+
+@example
+@verbatiminclude tutorial-examples/021.c
+@end example
+
+@noindent
+Note that it is mandatory to detect duplicate replies in this function
+and return the respective status code. Duplicate detection is
+typically done using the Bloom filter block group provided by
+@file{libgnunetblockgroup.so}. Failure to do so may cause replies to
+circle in the network.
+
+@node Deriving a key from a reply
+@subsubsection Deriving a key from a reply
+
+The DHT can operate more efficiently if it is possible to derive a key
+from the value of the corresponding block. The @code{get\_key}
+function is used to obtain the key of a block --- for example, by
+means of hashing. If deriving the key is not possible, the function
+should simply return @code{GNUNET\_SYSERR} (the DHT will still work
+just fine with such blocks).
+
+@example
+@verbatiminclude tutorial-examples/022.c
+@end example
+
+@node Initialization of the plugin
+@subsubsection Initialization of the plugin
+
+The plugin is realized as a shared C library. The library must export
+an initialization function which should initialize the plugin. The
+initialization function specifies what block types the plugin cares
+about and returns a struct with the functions that are to be used for
+validation and obtaining keys (the ones just defined above).
+
+@example
+@verbatiminclude tutorial-examples/023.c
+@end example
+
+@node Shutdown of the plugin
+@subsubsection Shutdown of the plugin
+
+Following GNUnet's general plugin API concept, the plugin must
+export a second function for cleaning up. It usually does very
+little.
+
+@example
+@verbatiminclude tutorial-examples/024.c
+@end example
+
+@node Integration of the plugin with the build system
+@subsubsection Integration of the plugin with the build system
+
+In order to compile the plugin, the @file{Makefile.am} file for the
+service SERVICE should contain a rule similar to this:
+@c Actually this is a Makefile not C. But the whole structure of examples
+@c must be improved.
+
+@example
+@verbatiminclude tutorial-examples/025.c
+@end example
+
+@noindent
+Exercise: Write a block plugin that accepts all queries
+and all replies but prints information about queries and replies
+when the respective validation hooks are called.
+
+@node Monitoring the DHT
+@subsection Monitoring the DHT
+
+It is possible to monitor the functioning of the local
+DHT service. When monitoring the DHT, the service will
+alert the monitoring program of any events, both started
+locally or received for routing from another peer.
+The are three different types of events possible: a
+GET request, a PUT request or a response (a reply to a GET).
+
+Since the different events have different associated data,
+the API gets 3 different callbacks (one for each message type)
+and optional type and key parameters, to allow for filtering of
+messages. When an event happens, the appropiate callback is
+called with all the information about the event.
+
+@example
+@verbatiminclude tutorial-examples/026.c
+@end example
+
+@node Debugging with gnunet-arm
+@section Debugging with gnunet-arm
+
+Even if services are managed by @command{gnunet-arm}, you can
+start them with @command{gdb} or @command{valgrind}. For
+example, you could add the following lines to your
+configuration file to start the DHT service in a @command{gdb}
+session in a fresh @command{xterm}:
+
+@example
+[dht]
+PREFIX=xterm -e gdb --args
+@end example
+
+@noindent
+Alternatively, you can stop a service that was started via
+ARM and run it manually:
+
+@example
+$ gnunet-arm -k dht
+$ gdb --args gnunet-service-dht -L DEBUG
+$ valgrind gnunet-service-dht -L DEBUG
+@end example
+
+@noindent
+Assuming other services are well-written, they will automatically
+re-integrate the restarted service with the peer.
+
+GNUnet provides a powerful logging mechanism providing log
+levels @code{ERROR}, @code{WARNING}, @code{INFO} and @code{DEBUG}.
+The current log level is configured using the @code{$GNUNET_FORCE_LOG}
+environmental variable. The @code{DEBUG} level is only available if
+@command{--enable-logging=verbose} was used when running
+@command{configure}. More details about logging can be found under
+@uref{https://gnunet.org/logging}.
+
+You should also probably enable the creation of core files, by setting
+@code{ulimit}, and echo'ing @code{1} into
+@file{/proc/sys/kernel/core\_uses\_pid}. Then you can investigate the
+core dumps with @command{gdb}, which is often the fastest method to
+find simple errors.
+
+Exercise: Add a memory leak to your service and obtain a trace
+pointing to the leak using @command{valgrind} while running the service
+from @command{gnunet-service-arm}.
+
+@bye
--- /dev/null
+\input texinfo
+@c -*-texinfo-*-
+
+@c %**start of header
+@setfilename gnunet.info
+@documentencoding UTF-8
+@settitle GNUnet Reference Manual
+@exampleindent 2
+@c %**end of header
+
+@include version.texi
+
+@c Set Versions which might be used in more than one place:
+@set GNUNET-DIST-URL https://ftp.gnu.org/gnu/gnunet/
+@set GNUNET-VERSION 0.10.1
+@set GNURL-VERSION-CURRENT 7.55.1
+@set GNURL-DIST-URL https://gnunet.org/sites/default/files/
+@c @set OPENPGP-SIGNING-KEY-ID
+
+@copying
+Copyright @copyright{} 2001-2017 GNUnet e.V.
+
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.3 or
+any later version published by the Free Software Foundation; with no
+Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A
+copy of the license is included in the section entitled ``GNU Free
+Documentation License''.
+
+A copy of the license is also available from the Free Software
+Foundation Web site at @url{http://www.gnu.org/licenses/fdl.html}.
+
+Alternately, this document is also available under the General
+Public License, version 3 or later, as published by the Free Software
+Foundation. A copy of the license is included in the section entitled
+``GNU General Public License''.
+
+A copy of the license is also available from the Free Software
+Foundation Web site at @url{http://www.gnu.org/licenses/gpl.html}.
+@end copying
+
+@c TODO: Improve this and improve https://directory.fsf.org/wiki/Gnunet
+
+@dircategory Networking
+@direntry
+* GNUnet: (gnunet). Framework for secure peer-to-peer networking
+@end direntry
+
+@titlepage
+@title GNUnet Reference Manual
+@subtitle Installing, configuring, using and contributing to GNUnet
+@author The GNUnet Developers
+
+@page
+@vskip 0pt plus 1filll
+Edition @value{EDITION} @*
+@value{UPDATED} @*
+
+@insertcopying
+@end titlepage
+
+@summarycontents
+@contents
+
+@node Top
+@top Contributing to GNUnet
+
+
+This document describes GNUnet version @value{VERSION}.
+
+
+GNUnet is a @uref{http://www.gnu.org/, GNU} package.
+All code contributions must thus be put under the
+@uref{http://www.gnu.org/copyleft/gpl.html, GNU Public License (GPL)}.
+All documentation should be put under FSF approved licenses
+(see @uref{http://www.gnu.org/copyleft/fdl.html, fdl}).
+
+By submitting documentation, translations, comments and other
+content to this website you automatically grant the right to publish
+code under the GNU Public License and documentation under either or
+both the GNU Public License or the GNU Free Documentation License.
+When contributing to the GNUnet project, GNU standards and the
+@uref{http://www.gnu.org/philosophy/philosophy.html, GNU philosophy}
+should be adhered to.
+
+Note that we do now require a formal copyright assignment for GNUnet
+contributors to GNUnet e.V.; nevertheless, we do allow pseudonymous
+contributions. By signing the copyright agreement and submitting your
+code (or documentation) to us, you agree to share the rights to your
+code with GNUnet e.V.; GNUnet e.V. receives non-exclusive ownership
+rights, and in particular is allowed to dual-license the code. You
+retain non-exclusive rights to your contributions, so you can also
+share your contributions freely with other projects.
+
+GNUnet e.V. will publish all accepted contributions under the GPLv3
+or any later version. The association may decide to publish
+contributions under additional licenses (dual-licensing).
+
+We do not intentionally remove your name from your contributions;
+however, due to extensive editing it is not always trivial to
+attribute contributors properly. If you find that you significantly
+contributed to a file (or the project as a whole) and are not listed
+in the respective authors file or section, please do let us know.
+
+
+
+@menu
+
+* Philosophy:: About GNUnet
+* Vocabulary:: Vocabulary
+* GNUnet Installation Handbook:: How to install GNUnet
+* Using GNUnet:: Using GNUnet
+* GNUnet Developer Handbook:: Developing GNUnet
+* GNU Free Documentation License:: The license of this manual.
+* GNU General Public License:: The license of this manual.
+* Concept Index:: Concepts.
+* Programming Index:: Data types, functions, and variables.
+
+@detailmenu
+ --- The Detailed Node Listing ---
+
+Philosophy
+
+* Design Goals::
+* Security & Privacy::
+* Versatility::
+* Practicality::
+* Key Concepts::
+* Authentication::
+* Accounting to Encourage Resource Sharing::
+* Confidentiality::
+* Anonymity::
+* Deniability::
+* Peer Identities::
+* Zones in the GNU Name System (GNS Zones)::
+* Egos::
+* Backup of Identities and Egos::
+* Revocation::
+
+Vocabulary
+
+* Words and characters::
+* Technical Assumptions::
+
+GNUnet Installation Handbook
+
+* Dependencies::
+* Pre-installation notes::
+* Generic installation instructions::
+* Build instructions for Ubuntu 12.04 using Git::
+* Build Instructions for Microsoft Windows Platforms::
+* Build instructions for Debian 7.5::
+* Installing GNUnet from Git on Ubuntu 14.4::
+* Build instructions for Debian 8::
+* Outdated build instructions for previous revisions::
+* Portable GNUnet::
+* The graphical configuration interface::
+* How to start and stop a GNUnet peer::
+
+Using GNUnet
+
+* Checking the Installation::
+* First steps - File-sharing::
+* First steps - Using the GNU Name System::
+* First steps - Using GNUnet Conversation::
+* First steps - Using the GNUnet VPN::
+* File-sharing::
+* The GNU Name System::
+* Using the Virtual Public Network::
+
+GNUnet Developer Handbook
+
+* Developer Introduction::
+* Code overview::
+* System Architecture::
+* Subsystem stability::
+* Naming conventions and coding style guide::
+* Build-system::
+* Developing extensions for GNUnet using the gnunet-ext template::
+* Writing testcases::
+* GNUnet's TESTING library::
+* Performance regression analysis with Gauger::
+* GNUnet's TESTBED Subsystem::
+* libgnunetutil::
+* The Automatic Restart Manager (ARM)::
+* GNUnet's TRANSPORT Subsystem::
+* NAT library::
+* Distance-Vector plugin::
+* SMTP plugin::
+* Bluetooth plugin::
+* WLAN plugin::
+* The ATS Subsystem::
+* GNUnet's CORE Subsystem::
+* GNUnet's CADET subsystem::
+* GNUnet's NSE subsystem::
+* GNUnet's HOSTLIST subsystem::
+* GNUnet's IDENTITY subsystem::
+* GNUnet's NAMESTORE Subsystem::
+* GNUnet's PEERINFO subsystem::
+* GNUnet's PEERSTORE subsystem::
+* GNUnet's SET Subsystem::
+* GNUnet's STATISTICS subsystem::
+* GNUnet's Distributed Hash Table (DHT)::
+* The GNU Name System (GNS)::
+* The GNS Namecache::
+* The REVOCATION Subsystem::
+* GNUnet's File-sharing (FS) Subsystem::
+* GNUnet's REGEX Subsystem::
+
+@end detailmenu
+@end menu
+
+@c *********************************************************************
+@include chapters/philosophy.texi
+@c *********************************************************************
+
+@include chapters/vocabulary.texi
+
+@c *********************************************************************
+@include chapters/installation.texi
+@c *********************************************************************
+
+@c *********************************************************************
+@include chapters/user.texi
+@c *********************************************************************
+
+@c *********************************************************************
+@include chapters/developer.texi
+@c @include gnunet-c-tutorial.texi
+@c *********************************************************************
+
+@c *********************************************************************
+@node GNU Free Documentation License
+@appendix GNU Free Documentation License
+@cindex license, GNU Free Documentation License
+@include fdl-1.3.texi
+
+@c *********************************************************************
+@node GNU General Public License
+@appendix GNU General Public License
+@cindex license, GNU General Public License
+@include gpl-3.0.texi
+
+@c *********************************************************************
+@node Concept Index
+@unnumbered Concept Index
+@printindex cp
+
+@node Programming Index
+@unnumbered Programming Index
+@syncodeindex tp fn
+@syncodeindex vr fn
+@printindex fn
+
+@bye
--- /dev/null
+@c The GNU General Public License.
+@center Version 3, 29 June 2007
+
+@c This file is intended to be included within another document,
+@c hence no sectioning command or @node.
+
+@display
+Copyright @copyright{} 2007 Free Software Foundation, Inc. @url{http://fsf.org/}
+
+Everyone is permitted to copy and distribute verbatim copies of this
+license document, but changing it is not allowed.
+@end display
+
+@heading Preamble
+
+The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom
+to share and change all versions of a program---to make sure it remains
+free software for all its users. We, the Free Software Foundation,
+use the GNU General Public License for most of our software; it
+applies also to any other work released this way by its authors. You
+can apply it to your programs, too.
+
+When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you
+have certain responsibilities if you distribute copies of the
+software, or if you modify it: responsibilities to respect the freedom
+of others.
+
+For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too,
+receive or can get the source code. And you must show them these
+terms so they know their rights.
+
+Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the
+manufacturer can do so. This is fundamentally incompatible with the
+aim of protecting users' freedom to change the software. The
+systematic pattern of such abuse occurs in the area of products for
+individuals to use, which is precisely where it is most unacceptable.
+Therefore, we have designed this version of the GPL to prohibit the
+practice for those products. If such problems arise substantially in
+other domains, we stand ready to extend this provision to those
+domains in future versions of the GPL, as needed to protect the
+freedom of users.
+
+Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish
+to avoid the special danger that patents applied to a free program
+could make it effectively proprietary. To prevent this, the GPL
+assures that patents cannot be used to render the program non-free.
+
+The precise terms and conditions for copying, distribution and
+modification follow.
+
+@heading TERMS AND CONDITIONS
+
+@enumerate 0
+@item Definitions.
+
+``This License'' refers to version 3 of the GNU General Public License.
+
+``Copyright'' also means copyright-like laws that apply to other kinds
+of works, such as semiconductor masks.
+
+``The Program'' refers to any copyrightable work licensed under this
+License. Each licensee is addressed as ``you''. ``Licensees'' and
+``recipients'' may be individuals or organizations.
+
+To ``modify'' a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of
+an exact copy. The resulting work is called a ``modified version'' of
+the earlier work or a work ``based on'' the earlier work.
+
+A ``covered work'' means either the unmodified Program or a work based
+on the Program.
+
+To ``propagate'' a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+To ``convey'' a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user
+through a computer network, with no transfer of a copy, is not
+conveying.
+
+An interactive user interface displays ``Appropriate Legal Notices'' to
+the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+@item Source Code.
+
+The ``source code'' for a work means the preferred form of the work for
+making modifications to it. ``Object code'' means any non-source form
+of a work.
+
+A ``Standard Interface'' means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+The ``System Libraries'' of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+``Major Component'', in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+The ``Corresponding Source'' for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+The Corresponding Source need not include anything that users can
+regenerate automatically from other parts of the Corresponding Source.
+
+The Corresponding Source for a work in source code form is that same
+work.
+
+@item Basic Permissions.
+
+All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+You may make, run and propagate covered works that you do not convey,
+without conditions so long as your license otherwise remains in force.
+You may convey covered works to others for the sole purpose of having
+them make modifications exclusively for you, or provide you with
+facilities for running those works, provided that you comply with the
+terms of this License in conveying all material for which you do not
+control copyright. Those thus making or running the covered works for
+you must do so exclusively on your behalf, under your direction and
+control, on terms that prohibit them from making any copies of your
+copyrighted material outside their relationship with you.
+
+Conveying under any other circumstances is permitted solely under the
+conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+@item Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such
+circumvention is effected by exercising rights under this License with
+respect to the covered work, and you disclaim any intention to limit
+operation or modification of the work as a means of enforcing, against
+the work's users, your or third parties' legal rights to forbid
+circumvention of technological measures.
+
+@item Conveying Verbatim Copies.
+
+You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+@item Conveying Modified Source Versions.
+
+You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these
+conditions:
+
+@enumerate a
+@item
+The work must carry prominent notices stating that you modified it,
+and giving a relevant date.
+
+@item
+The work must carry prominent notices stating that it is released
+under this License and any conditions added under section 7. This
+requirement modifies the requirement in section 4 to ``keep intact all
+notices''.
+
+@item
+You must license the entire work, as a whole, under this License to
+anyone who comes into possession of a copy. This License will
+therefore apply, along with any applicable section 7 additional terms,
+to the whole of the work, and all its parts, regardless of how they
+are packaged. This License gives no permission to license the work in
+any other way, but it does not invalidate such permission if you have
+separately received it.
+
+@item
+If the work has interactive user interfaces, each must display
+Appropriate Legal Notices; however, if the Program has interactive
+interfaces that do not display Appropriate Legal Notices, your work
+need not make them do so.
+@end enumerate
+
+A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+``aggregate'' if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+@item Conveying Non-Source Forms.
+
+You may convey a covered work in object code form under the terms of
+sections 4 and 5, provided that you also convey the machine-readable
+Corresponding Source under the terms of this License, in one of these
+ways:
+
+@enumerate a
+@item
+Convey the object code in, or embodied in, a physical product
+(including a physical distribution medium), accompanied by the
+Corresponding Source fixed on a durable physical medium customarily
+used for software interchange.
+
+@item
+Convey the object code in, or embodied in, a physical product
+(including a physical distribution medium), accompanied by a written
+offer, valid for at least three years and valid for as long as you
+offer spare parts or customer support for that product model, to give
+anyone who possesses the object code either (1) a copy of the
+Corresponding Source for all the software in the product that is
+covered by this License, on a durable physical medium customarily used
+for software interchange, for a price no more than your reasonable
+cost of physically performing this conveying of source, or (2) access
+to copy the Corresponding Source from a network server at no charge.
+
+@item
+Convey individual copies of the object code with a copy of the written
+offer to provide the Corresponding Source. This alternative is
+allowed only occasionally and noncommercially, and only if you
+received the object code with such an offer, in accord with subsection
+6b.
+
+@item
+Convey the object code by offering access from a designated place
+(gratis or for a charge), and offer equivalent access to the
+Corresponding Source in the same way through the same place at no
+further charge. You need not require recipients to copy the
+Corresponding Source along with the object code. If the place to copy
+the object code is a network server, the Corresponding Source may be
+on a different server (operated by you or a third party) that supports
+equivalent copying facilities, provided you maintain clear directions
+next to the object code saying where to find the Corresponding Source.
+Regardless of what server hosts the Corresponding Source, you remain
+obligated to ensure that it is available for as long as needed to
+satisfy these requirements.
+
+@item
+Convey the object code using peer-to-peer transmission, provided you
+inform other peers where the object code and Corresponding Source of
+the work are being offered to the general public at no charge under
+subsection 6d.
+
+@end enumerate
+
+A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+A ``User Product'' is either (1) a ``consumer product'', which means any
+tangible personal property which is normally used for personal,
+family, or household purposes, or (2) anything designed or sold for
+incorporation into a dwelling. In determining whether a product is a
+consumer product, doubtful cases shall be resolved in favor of
+coverage. For a particular product received by a particular user,
+``normally used'' refers to a typical or common use of that class of
+product, regardless of the status of the particular user or of the way
+in which the particular user actually uses, or expects or is expected
+to use, the product. A product is a consumer product regardless of
+whether the product has substantial commercial, industrial or
+non-consumer uses, unless such uses represent the only significant
+mode of use of the product.
+
+``Installation Information'' for a User Product means any methods,
+procedures, authorization keys, or other information required to
+install and execute modified versions of a covered work in that User
+Product from a modified version of its Corresponding Source. The
+information must suffice to ensure that the continued functioning of
+the modified object code is in no case prevented or interfered with
+solely because modification has been made.
+
+If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or
+updates for a work that has been modified or installed by the
+recipient, or for the User Product in which it has been modified or
+installed. Access to a network may be denied when the modification
+itself materially and adversely affects the operation of the network
+or violates the rules and protocols for communication across the
+network.
+
+Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+@item Additional Terms.
+
+``Additional permissions'' are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders
+of that material) supplement the terms of this License with terms:
+
+@enumerate a
+@item
+Disclaiming warranty or limiting liability differently from the terms
+of sections 15 and 16 of this License; or
+
+@item
+Requiring preservation of specified reasonable legal notices or author
+attributions in that material or in the Appropriate Legal Notices
+displayed by works containing it; or
+
+@item
+Prohibiting misrepresentation of the origin of that material, or
+requiring that modified versions of such material be marked in
+reasonable ways as different from the original version; or
+
+@item
+Limiting the use for publicity purposes of names of licensors or
+authors of the material; or
+
+@item
+Declining to grant rights under trademark law for use of some trade
+names, trademarks, or service marks; or
+
+@item
+Requiring indemnification of licensors and authors of that material by
+anyone who conveys the material (or modified versions of it) with
+contractual assumptions of liability to the recipient, for any
+liability that these contractual assumptions directly impose on those
+licensors and authors.
+@end enumerate
+
+All other non-permissive additional terms are considered ``further
+restrictions'' within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions; the
+above requirements apply either way.
+
+@item Termination.
+
+You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+However, if you cease all violation of this License, then your license
+from a particular copyright holder is reinstated (a) provisionally,
+unless and until the copyright holder explicitly and finally
+terminates your license, and (b) permanently, if the copyright holder
+fails to notify you of the violation by some reasonable means prior to
+60 days after the cessation.
+
+Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+@item Acceptance Not Required for Having Copies.
+
+You are not required to accept this License in order to receive or run
+a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+@item Automatic Licensing of Downstream Recipients.
+
+Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+An ``entity transaction'' is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+@item Patents.
+
+A ``contributor'' is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's ``contributor version''.
+
+A contributor's ``essential patent claims'' are all patent claims owned
+or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, ``control'' includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+In the following three paragraphs, a ``patent license'' is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To ``grant'' such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. ``Knowingly relying'' means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+A patent license is ``discriminatory'' if it does not include within the
+scope of its coverage, prohibits the exercise of, or is conditioned on
+the non-exercise of one or more of the rights that are specifically
+granted under this License. You may not convey a covered work if you
+are a party to an arrangement with a third party that is in the
+business of distributing software, under which you make payment to the
+third party based on the extent of your activity of conveying the
+work, and under which the third party grants, to any of the parties
+who would receive the covered work from you, a discriminatory patent
+license (a) in connection with copies of the covered work conveyed by
+you (or copies made from those copies), or (b) primarily for and in
+connection with specific products or compilations that contain the
+covered work, unless you entered into that arrangement, or that patent
+license was granted, prior to 28 March 2007.
+
+Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+@item No Surrender of Others' Freedom.
+
+If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey
+a covered work so as to satisfy simultaneously your obligations under
+this License and any other pertinent obligations, then as a
+consequence you may not convey it at all. For example, if you agree
+to terms that obligate you to collect a royalty for further conveying
+from those to whom you convey the Program, the only way you could
+satisfy both those terms and this License would be to refrain entirely
+from conveying the Program.
+
+@item Use with the GNU Affero General Public License.
+
+Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+@item Revised Versions of this License.
+
+The Free Software Foundation may publish revised and/or new versions
+of the GNU General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies that a certain numbered version of the GNU General Public
+License ``or any later version'' applies to it, you have the option of
+following the terms and conditions either of that numbered version or
+of any later version published by the Free Software Foundation. If
+the Program does not specify a version number of the GNU General
+Public License, you may choose any version ever published by the Free
+Software Foundation.
+
+If the Program specifies that a proxy can decide which future versions
+of the GNU General Public License can be used, that proxy's public
+statement of acceptance of a version permanently authorizes you to
+choose that version for the Program.
+
+Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+@item Disclaimer of Warranty.
+
+THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW@. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM ``AS IS'' WITHOUT
+WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE@. THE ENTIRE RISK AS TO THE QUALITY AND
+PERFORMANCE OF THE PROGRAM IS WITH YOU@. SHOULD THE PROGRAM PROVE
+DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
+CORRECTION.
+
+@item Limitation of Liability.
+
+IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR
+CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES
+ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT
+NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR
+LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM
+TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER
+PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+@item Interpretation of Sections 15 and 16.
+
+If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+@end enumerate
+
+@heading END OF TERMS AND CONDITIONS
+
+@heading How to Apply These Terms to Your New Programs
+
+If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these
+terms.
+
+To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the ``copyright'' line and a pointer to where the full notice is found.
+
+@smallexample
+@var{one line to give the program's name and a brief idea of what it does.}
+Copyright (C) @var{year} @var{name of author}
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or (at
+your option) any later version.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE@. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see @url{http://www.gnu.org/licenses/}.
+@end smallexample
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+@smallexample
+@var{program} Copyright (C) @var{year} @var{name of author}
+This program comes with ABSOLUTELY NO WARRANTY; for details type @samp{show w}.
+This is free software, and you are welcome to redistribute it
+under certain conditions; type @samp{show c} for details.
+@end smallexample
+
+The hypothetical commands @samp{show w} and @samp{show c} should show
+the appropriate parts of the General Public License. Of course, your
+program's commands might be different; for a GUI interface, you would
+use an ``about box''.
+
+You should also get your employer (if you work as a programmer) or school,
+if any, to sign a ``copyright disclaimer'' for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+@url{http://www.gnu.org/licenses/}.
+
+The GNU General Public License does not permit incorporating your
+program into proprietary programs. If your program is a subroutine
+library, you may consider it more useful to permit linking proprietary
+applications with the library. If this is what you want to do, use
+the GNU Lesser General Public License instead of this License. But
+first, please read @url{http://www.gnu.org/philosophy/why-not-lgpl.html}.
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="744.09448819"
+ height="1052.3622047"
+ id="svg6781"
+ version="1.1"
+ inkscape:version="0.48.2 r9819"
+ sodipodi:docname="New document 58">
+ <defs
+ id="defs6783" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="0.35"
+ inkscape:cx="375"
+ inkscape:cy="520"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:window-width="1366"
+ inkscape:window-height="721"
+ inkscape:window-x="-2"
+ inkscape:window-y="-3"
+ inkscape:window-maximized="1" />
+ <metadata
+ id="metadata6786">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1">
+ <g
+ transform="translate(-4.5298577,-148.04661)"
+ id="g6746">
+ <path
+ style="fill:#5fd38d;fill-opacity:1;stroke:#faf6a2;stroke-width:1.99014676;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
+ d="m 183.84284,595.7683 350.8064,0 0,202.04036 -350.8064,0 z"
+ id="path6693"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;stroke:#faf6a2;stroke-width:2.22747946;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect6695"
+ width="66.670067"
+ height="75.18058"
+ x="223.74881"
+ y="737.19458" />
+ <rect
+ y="737.19458"
+ x="331.83514"
+ height="67.323441"
+ width="66.670067"
+ id="rect6697"
+ style="fill:#ffffff;fill-opacity:1;stroke:#faf6a2;stroke-width:2.10787106;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;stroke:#faf6a2;stroke-width:2.06117821;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect6699"
+ width="66.670067"
+ height="64.373825"
+ x="434.8707"
+ y="737.19458" />
+ <path
+ style="fill:#37c871;fill-opacity:1;stroke:#faf6a2;stroke-width:0.98368376;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
+ d="m 223.60976,736.21851 67.23534,0.38374 0,23.63648 -67.23534,37.13818 z"
+ id="path6701"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0"
+ id="path6703"
+ d="m 331.69608,736.21851 67.23534,0.3894 0,23.98466 -67.23534,37.68524 z"
+ style="fill:#37c871;fill-opacity:1;stroke:#faf6a2;stroke-width:0.99090236;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" />
+ <path
+ style="fill:#37c871;fill-opacity:1;stroke:#faf6a2;stroke-width:0.98368376;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
+ d="m 434.73164,736.21851 67.23534,0.38374 0,23.63648 -67.23534,37.13818 z"
+ id="path6705"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ style="fill:#37c871;fill-opacity:1;stroke:#faf6a2;stroke-width:1.92068994;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
+ d="m 533.72659,595.02309 56.12366,-29.34622 -1.01015,190.24271 -55.11351,41.45733 z"
+ id="path6707"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ style="fill:#37c871;fill-opacity:1;stroke:#faf6a2;stroke-width:1.99424875;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
+ d="m 245.46708,566.47881 345.46203,-1.01015 -56.56854,31.31472 -349.50264,-1.01014 z"
+ id="path6709"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc" />
+ <text
+ sodipodi:linespacing="125%"
+ id="text6715"
+ y="677.59558"
+ x="234.35539"
+ style="font-size:36px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ xml:space="preserve"><tspan
+ y="677.59558"
+ x="234.35539"
+ id="tspan6717"
+ sodipodi:role="line">User Interface</tspan></text>
+ </g>
+ </g>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="744.09448819"
+ height="1052.3622047"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.1 r9760"
+ sodipodi:docname="System.svg">
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient6602">
+ <stop
+ style="stop-color:#df8060;stop-opacity:1;"
+ offset="0"
+ id="stop6604" />
+ <stop
+ style="stop-color:#df8002;stop-opacity:0;"
+ offset="1"
+ id="stop6606" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4392"
+ osb:paint="solid">
+ <stop
+ style="stop-color:#faf6a6;stop-opacity:1;"
+ offset="0"
+ id="stop4394" />
+ </linearGradient>
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="883.99395 : 559.99673 : 1"
+ inkscape:vp_y="13.319386 : 993.87659 : 0"
+ inkscape:vp_z="285.3157 : 504.79962 : 1"
+ inkscape:persp3d-origin="481.39556 : 281.96355 : 1"
+ id="perspective3070" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="76.097926 : 349.87282 : 1"
+ inkscape:vp_y="-13.319386 : 979.366 : 0"
+ inkscape:vp_z="752.55793 : 376.31441 : 1"
+ inkscape:persp3d-origin="373.64045 : 350.98006 : 1"
+ id="perspective3012" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="0.98994949"
+ inkscape:cx="322.06882"
+ inkscape:cy="568.82291"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:window-width="846"
+ inkscape:window-height="963"
+ inkscape:window-x="59"
+ inkscape:window-y="0"
+ inkscape:window-maximized="0" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1">
+ <text
+ xml:space="preserve"
+ style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="352.03815"
+ y="-190.12544"
+ id="text6623"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan6625"
+ x="352.03815"
+ y="-190.12544" /></text>
+ <text
+ xml:space="preserve"
+ style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="338.40109"
+ y="-300.73715"
+ id="text6627"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan6629"
+ x="338.40109"
+ y="-300.73715" /></text>
+ <g
+ style="font-size:24px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ id="text6643" />
+ <text
+ xml:space="preserve"
+ style="font-size:24px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="71.720833"
+ y="95.747719"
+ id="text6648"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan6650"
+ x="71.720833"
+ y="95.747719" /></text>
+ <text
+ xml:space="preserve"
+ style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="262.63965"
+ y="666.48389"
+ id="text6711"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan6713"
+ x="262.63965"
+ y="666.48389" /></text>
+ <path
+ inkscape:connector-curvature="0"
+ id="path3506"
+ d="m 198.00647,673.76257 236.93358,0 0,158.2919 -236.93358,0 z"
+ style="fill:#000000;fill-opacity:1;stroke:#faf6a2;stroke-width:1.44768786;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0"
+ id="path3432"
+ d="m 169.32669,654.90334 464.83332,-2.26992 -33.76593,25.73079 -483.97287,-0.12904 z"
+ style="fill:#deaa87;fill-opacity:1;stroke:#faf6a2;stroke-width:2.18398547;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" />
+ <rect
+ style="fill:#000000;fill-opacity:1;stroke:#59000c;stroke-width:1.35822594;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0.48230088;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect3416"
+ width="28.495705"
+ height="172.2845"
+ x="464.19418"
+ y="518.96954" />
+ <rect
+ style="fill:#000000;fill-opacity:1;stroke:#59000c;stroke-width:1.36876941;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0.48230088;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect3414"
+ width="34.729141"
+ height="170.67587"
+ x="340.86124"
+ y="517.93475" />
+ <path
+ style="fill:#deaa87;fill-opacity:1;stroke:#faf6a2;stroke-width:2.04969239;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
+ d="m 246.8138,499.06358 386.50295,-0.94821 -41.88736,26.04231 -413.96081,0 z"
+ id="rect6568-0"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ style="fill:#ffdd55;fill-opacity:1;stroke:#faf6a2;stroke-width:1.49989259;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
+ d="m 276.05867,399.52042 323.05541,0 0,124.61741 -323.05541,0 z"
+ id="rect5973"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffcc00;fill-opacity:1;stroke:#faf6a2;stroke-width:1.19094384;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
+ d="m 599.16863,399.06078 34.35465,-18.10059 0,117.34068 -34.35465,25.57066 z"
+ id="rect6542"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc" />
+ <rect
+ style="fill:#c87137;fill-opacity:1;stroke:#c48069;stroke-width:1.50087094;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect6557"
+ width="322.88623"
+ height="30.529778"
+ x="276.67755"
+ y="368.99368" />
+ <path
+ style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:0.50882494;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
+ d="m 598.94047,368.99367 34.58281,-16.82253 0,28.66061 -34.58281,18.06864 z"
+ id="rect6561"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0"
+ id="path6564"
+ d="m 598.94047,369.07046 34.30741,-17.12981 0,29.18412 -34.30741,18.39868 z"
+ style="fill:#c87137;fill-opacity:1;stroke:#faf6a2;stroke-width:0.51140249;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
+ inkscape:transform-center-x="-70.147578"
+ inkscape:transform-center-y="15.429055" />
+ <path
+ style="fill:#d38d5f;fill-opacity:1;stroke:#faf6a2;stroke-width:1.47079194;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
+ d="m 330.2508,353.23478 302.87005,-0.62306 -38.33414,16.82253 -318.87597,0 z"
+ id="rect6568"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc" />
+ <text
+ xml:space="preserve"
+ style="font-size:22.32217598px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="391.63083"
+ y="461.858"
+ id="text6656"
+ sodipodi:linespacing="125%"
+ transform="scale(1.0052948,0.9947331)"><tspan
+ sodipodi:role="line"
+ id="tspan6658"
+ x="391.63083"
+ y="461.858">Service</tspan></text>
+ <path
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0"
+ id="path6707"
+ d="m 598.75503,244.83802 34.98432,-18.10059 0.26082,125.2709 -35.24514,17.64044 z"
+ style="fill:#37c871;fill-opacity:1;stroke:#faf6a2;stroke-width:1.19094384;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0"
+ id="path6709"
+ d="m 419.07032,228.1132 214.71185,-1.24611 -34.63196,19.9378 L 381.29,246.18184 z"
+ style="fill:#37c871;fill-opacity:1;stroke:#faf6a2;stroke-width:1.23655474;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" />
+ <rect
+ style="fill:#5fd38d;fill-opacity:1;stroke:#c48069;stroke-width:1.23640049;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect7224"
+ width="217.86653"
+ height="122.74216"
+ x="381.70358"
+ y="246.25151" />
+ <text
+ xml:space="preserve"
+ style="font-size:22.32217598px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="409.16376"
+ y="302.05649"
+ id="text6715"
+ sodipodi:linespacing="125%"
+ transform="scale(1.0052948,0.9947331)"><tspan
+ sodipodi:role="line"
+ id="tspan6717"
+ x="409.16376"
+ y="302.05649">User Interface</tspan></text>
+ <g
+ id="g7219"
+ transform="matrix(0.62334353,0,0,0.61679464,281.18563,257.70936)">
+ <rect
+ y="119.99139"
+ x="198.49498"
+ height="60.609154"
+ width="66.670067"
+ id="rect6571"
+ style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" />
+ <text
+ sodipodi:linespacing="125%"
+ id="text6631"
+ y="160.39748"
+ x="206.07112"
+ style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ xml:space="preserve"><tspan
+ y="160.39748"
+ x="206.07112"
+ id="tspan6633"
+ sodipodi:role="line">API</tspan></text>
+ </g>
+ <g
+ transform="matrix(0.62334353,0,0,0.61679464,344.78251,257.70936)"
+ id="g7226">
+ <rect
+ style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect7228"
+ width="66.670067"
+ height="60.609154"
+ x="198.49498"
+ y="119.99139" />
+ <text
+ xml:space="preserve"
+ style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="206.07112"
+ y="160.39748"
+ id="text7230"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan7232"
+ x="206.07112"
+ y="160.39748">API</tspan></text>
+ </g>
+ <g
+ id="g7234"
+ transform="matrix(0.62334353,0,0,0.61679464,409.3239,257.70936)">
+ <rect
+ y="119.99139"
+ x="198.49498"
+ height="60.609154"
+ width="66.670067"
+ id="rect7236"
+ style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" />
+ <text
+ sodipodi:linespacing="125%"
+ id="text7238"
+ y="160.39748"
+ x="206.07112"
+ style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ xml:space="preserve"><tspan
+ y="160.39748"
+ x="206.07112"
+ id="tspan7240"
+ sodipodi:role="line">API</tspan></text>
+ </g>
+ <g
+ transform="matrix(0.62334353,0,0,0.61679464,175.75806,412.85048)"
+ id="g7242">
+ <rect
+ style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect7244"
+ width="66.670067"
+ height="60.609154"
+ x="198.49498"
+ y="119.99139" />
+ <text
+ xml:space="preserve"
+ style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="206.07112"
+ y="160.39748"
+ id="text7246"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan7248"
+ x="206.07112"
+ y="160.39748">API</tspan></text>
+ </g>
+ <g
+ id="g7250"
+ transform="matrix(0.62334353,0,0,0.61679464,240.79871,413.29105)">
+ <rect
+ y="119.99139"
+ x="198.49498"
+ height="60.609154"
+ width="66.670067"
+ id="rect7252"
+ style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" />
+ <text
+ sodipodi:linespacing="125%"
+ id="text7254"
+ y="160.39748"
+ x="206.07112"
+ style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ xml:space="preserve"><tspan
+ y="160.39748"
+ x="206.07112"
+ id="tspan7256"
+ sodipodi:role="line">API</tspan></text>
+ </g>
+ <g
+ transform="matrix(0.62334353,0,0,0.61679464,303.79756,412.40991)"
+ id="g7258">
+ <rect
+ style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect7260"
+ width="66.670067"
+ height="60.609154"
+ x="198.49498"
+ y="119.99139" />
+ <text
+ xml:space="preserve"
+ style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="206.07112"
+ y="160.39748"
+ id="text7262"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan7264"
+ x="206.07112"
+ y="160.39748">API</tspan></text>
+ </g>
+ <g
+ id="g7266"
+ transform="matrix(0.62334353,0,0,0.61679464,369.88148,412.40991)">
+ <rect
+ y="119.99139"
+ x="198.49498"
+ height="60.609154"
+ width="66.670067"
+ id="rect7268"
+ style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" />
+ <text
+ sodipodi:linespacing="125%"
+ id="text7270"
+ y="160.39748"
+ x="206.07112"
+ style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ xml:space="preserve"><tspan
+ y="160.39748"
+ x="206.07112"
+ id="tspan7272"
+ sodipodi:role="line">API</tspan></text>
+ </g>
+ <path
+ style="fill:#ffeeaa;fill-opacity:1;stroke:#faf6a2;stroke-width:0.91879815;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
+ d="m 478.56081,554.09281 121.22633,0 0,124.61741 -121.22633,0 z"
+ id="rect5973-1"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="matrix(0.62334353,0,0,0.61679464,422.424,566.60858)"
+ id="g3474">
+ <rect
+ style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect3476"
+ width="66.670067"
+ height="60.609154"
+ x="198.49498"
+ y="119.99139" />
+ <text
+ xml:space="preserve"
+ style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="206.07112"
+ y="160.39748"
+ id="text3478"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3480"
+ x="206.07112"
+ y="160.39748">API</tspan></text>
+ </g>
+ <path
+ style="fill:#ffe680;fill-opacity:1;stroke:#faf6a2;stroke-width:1.18771458;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
+ d="m 599.60339,554.02055 33.72575,-29.55535 0.88568,128.35487 -34.61143,26.01123 z"
+ id="rect6542-8"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0"
+ id="path6564-2"
+ d="m 598.92998,524.03024 34.30741,-25.94116 0,26.5407 -34.30741,29.85344 z"
+ style="fill:#d38d5f;fill-opacity:1;stroke:#faf6a2;stroke-width:0.51140249;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
+ inkscape:transform-center-x="-70.147578"
+ inkscape:transform-center-y="15.429055" />
+ <path
+ inkscape:transform-center-y="15.492457"
+ inkscape:transform-center-x="-70.147578"
+ style="fill:#c87137;fill-opacity:1;stroke:#faf6a2;stroke-width:0.51245213;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
+ d="m 598.92998,524.13683 34.30741,-26.04775 0,26.64977 -34.30741,29.97611 z"
+ id="path3402"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0"
+ id="path3404"
+ d="m 599.82047,678.2289 34.30741,-25.94116 0,26.5407 -34.30741,34.25912 z"
+ style="fill:#c87137;fill-opacity:1;stroke:#faf6a2;stroke-width:0.51140249;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
+ inkscape:transform-center-x="-70.147578"
+ inkscape:transform-center-y="15.429055" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0"
+ id="path3406"
+ d="m 600.04863,707.77865 33.90941,-29.55535 0.89049,128.35487 -34.7999,26.01123 z"
+ style="fill:#37c837;fill-opacity:1;stroke:#faf6a2;stroke-width:1.19094384;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path3410"
+ d="m 356.56358,554.09281 120.92249,0 0,124.19268 -120.92249,0 z"
+ style="fill:#ffeeaa;fill-opacity:1;stroke:#faf6a2;stroke-width:0.91608089;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" />
+ <path
+ style="fill:#ffeeaa;fill-opacity:1;stroke:#faf6a2;stroke-width:1.11023378;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
+ d="m 177.52518,554.09281 177.51841,0 0,124.25702 -177.51841,0 z"
+ id="path3412"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="fill:#c87137;fill-opacity:1;stroke:#c48069;stroke-width:1.11264122;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect6557-7"
+ width="177.44882"
+ height="30.529778"
+ x="177.65657"
+ y="523.95343" />
+ <rect
+ y="678.1521"
+ x="116.73995"
+ height="29.53463"
+ width="177.54182"
+ id="rect3408"
+ style="fill:#c87137;fill-opacity:1;stroke:#c48069;stroke-width:1.09464383;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" />
+ <rect
+ y="523.95343"
+ x="356.55023"
+ height="30.529778"
+ width="120.86897"
+ id="rect3420"
+ style="fill:#c87137;fill-opacity:1;stroke:#c48069;stroke-width:0.91828173;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" />
+ <rect
+ style="fill:#c87137;fill-opacity:1;stroke:#c48069;stroke-width:0.91828173;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect3422"
+ width="120.86897"
+ height="30.529778"
+ x="478.54919"
+ y="523.95343" />
+ <text
+ xml:space="preserve"
+ style="font-size:22.32217598px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="372.34232"
+ y="622.53217"
+ id="text6656-2"
+ sodipodi:linespacing="125%"
+ transform="scale(1.0052948,0.9947331)"><tspan
+ sodipodi:role="line"
+ id="tspan6658-2"
+ x="372.34232"
+ y="622.53217">Service</tspan></text>
+ <text
+ sodipodi:linespacing="125%"
+ id="text3424"
+ y="622.53217"
+ x="220.56013"
+ style="font-size:22.32217598px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ xml:space="preserve"
+ transform="scale(1.0052948,0.9947331)"><tspan
+ y="622.53217"
+ x="220.56013"
+ id="tspan3426"
+ sodipodi:role="line">Service</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:22.32217598px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="493.85532"
+ y="622.54492"
+ id="text3428"
+ sodipodi:linespacing="125%"
+ transform="scale(1.0052948,0.9947331)"><tspan
+ sodipodi:role="line"
+ id="tspan3430"
+ x="493.85532"
+ y="622.54492">Service</tspan></text>
+ <g
+ id="g3434"
+ transform="matrix(0.62334353,0,0,0.61679464,120.10238,566.60858)">
+ <rect
+ y="119.99139"
+ x="198.49498"
+ height="60.609154"
+ width="66.670067"
+ id="rect3436"
+ style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" />
+ <text
+ sodipodi:linespacing="125%"
+ id="text3438"
+ y="160.39748"
+ x="206.07112"
+ style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ xml:space="preserve"><tspan
+ y="160.39748"
+ x="206.07112"
+ id="tspan3440"
+ sodipodi:role="line">API</tspan></text>
+ </g>
+ <g
+ transform="matrix(0.62334353,0,0,0.61679464,181.54625,566.60858)"
+ id="g3442">
+ <rect
+ style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect3444"
+ width="66.670067"
+ height="60.609154"
+ x="198.49498"
+ y="119.99139" />
+ <text
+ xml:space="preserve"
+ style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="206.07112"
+ y="160.39748"
+ id="text3446"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3448"
+ x="206.07112"
+ y="160.39748">API</tspan></text>
+ </g>
+ <g
+ id="g3450"
+ transform="matrix(0.62334353,0,0,0.61679464,242.09962,566.60858)">
+ <rect
+ y="119.99139"
+ x="198.49498"
+ height="60.609154"
+ width="66.670067"
+ id="rect3452"
+ style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" />
+ <text
+ sodipodi:linespacing="125%"
+ id="text3454"
+ y="160.39748"
+ x="206.07112"
+ style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ xml:space="preserve"><tspan
+ y="160.39748"
+ x="206.07112"
+ id="tspan3456"
+ sodipodi:role="line">API</tspan></text>
+ </g>
+ <g
+ transform="matrix(0.62334353,0,0,0.61679464,303.54348,566.60858)"
+ id="g3458">
+ <rect
+ style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect3460"
+ width="66.670067"
+ height="60.609154"
+ x="198.49498"
+ y="119.99139" />
+ <text
+ xml:space="preserve"
+ style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="206.07112"
+ y="160.39748"
+ id="text3462"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3464"
+ x="206.07112"
+ y="160.39748">API</tspan></text>
+ </g>
+ <g
+ id="g3466"
+ transform="matrix(0.62334353,0,0,0.61679464,362.76112,566.60858)">
+ <rect
+ y="119.99139"
+ x="198.49498"
+ height="60.609154"
+ width="66.670067"
+ id="rect3468"
+ style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" />
+ <text
+ sodipodi:linespacing="125%"
+ id="text3470"
+ y="160.39748"
+ x="206.07112"
+ style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ xml:space="preserve"><tspan
+ y="160.39748"
+ x="206.07112"
+ id="tspan3472"
+ sodipodi:role="line">API</tspan></text>
+ </g>
+ <path
+ style="fill:#5fd35f;fill-opacity:1;stroke:#faf6a2;stroke-width:1.11993289;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
+ d="m 420.2626,707.53388 180.11119,0 0,124.61741 -180.11119,0 z"
+ id="path3490"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="matrix(0.62334353,0,0,0.61679464,62.665728,566.60858)"
+ id="g3492">
+ <rect
+ style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect3494"
+ width="66.670067"
+ height="60.609154"
+ x="198.49498"
+ y="119.99139" />
+ <text
+ xml:space="preserve"
+ style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="206.07112"
+ y="160.39748"
+ id="text3496"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3498"
+ x="206.07112"
+ y="160.39748">API</tspan></text>
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ id="path3500"
+ d="m 116.52597,707.54132 177.63643,0 0,124.61741 -177.63643,0 z"
+ style="fill:#5fd35f;fill-opacity:1;stroke:#faf6a2;stroke-width:1.11221218;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" />
+ <path
+ style="fill:#5fd35f;fill-opacity:1;stroke:#faf6a2;stroke-width:0.92545629;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
+ d="m 295.65636,707.63061 122.98965,0 0,124.61741 -122.98965,0 z"
+ id="path3502"
+ inkscape:connector-curvature="0" />
+ <text
+ xml:space="preserve"
+ style="font-size:22.32217598px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="162.54019"
+ y="779.76184"
+ id="text3508"
+ sodipodi:linespacing="125%"
+ transform="scale(1.0052948,0.9947331)"><tspan
+ sodipodi:role="line"
+ id="tspan3510"
+ x="162.54019"
+ y="779.76184">Service</tspan></text>
+ <text
+ sodipodi:linespacing="125%"
+ id="text3512"
+ y="779.7619"
+ x="313.56918"
+ style="font-size:22.32217598px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ xml:space="preserve"
+ transform="scale(1.0052948,0.9947331)"><tspan
+ y="779.7619"
+ x="313.56918"
+ id="tspan3514"
+ sodipodi:role="line">Service</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:22.32217598px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="465.48401"
+ y="779.7619"
+ id="text3516"
+ sodipodi:linespacing="125%"
+ transform="scale(1.0052948,0.9947331)"><tspan
+ sodipodi:role="line"
+ id="tspan3518"
+ x="465.48401"
+ y="779.7619">Service</tspan></text>
+ <rect
+ style="fill:#c87137;fill-opacity:1;stroke:#c48069;stroke-width:0.91063529;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect3520"
+ width="122.86946"
+ height="29.53463"
+ x="295.75125"
+ y="678.1521" />
+ <rect
+ y="678.1521"
+ x="420.27423"
+ height="29.53463"
+ width="179.80205"
+ id="rect3522"
+ style="fill:#c87137;fill-opacity:1;stroke:#c48069;stroke-width:1.10158956;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" />
+ </g>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="744.09448819"
+ height="1052.3622047"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.2 r9819"
+ sodipodi:docname="Lego block 3.svg">
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient6602">
+ <stop
+ style="stop-color:#df8060;stop-opacity:1;"
+ offset="0"
+ id="stop6604" />
+ <stop
+ style="stop-color:#df8002;stop-opacity:0;"
+ offset="1"
+ id="stop6606" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4392"
+ osb:paint="solid">
+ <stop
+ style="stop-color:#faf6a6;stop-opacity:1;"
+ offset="0"
+ id="stop4394" />
+ </linearGradient>
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="883.99395 : 559.99673 : 1"
+ inkscape:vp_y="13.319386 : 993.87659 : 0"
+ inkscape:vp_z="285.3157 : 504.79962 : 1"
+ inkscape:persp3d-origin="481.39556 : 281.96355 : 1"
+ id="perspective3070" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="76.097926 : 349.87282 : 1"
+ inkscape:vp_y="-13.319386 : 979.366 : 0"
+ inkscape:vp_z="752.55793 : 376.31441 : 1"
+ inkscape:persp3d-origin="373.64045 : 350.98006 : 1"
+ id="perspective3012" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="0.49497475"
+ inkscape:cx="385.59974"
+ inkscape:cy="826.03166"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:window-width="1366"
+ inkscape:window-height="721"
+ inkscape:window-x="-2"
+ inkscape:window-y="-3"
+ inkscape:window-maximized="1" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1">
+ <path
+ style="fill:#ffdd55;fill-opacity:1;stroke:#faf6a2;stroke-width:2.26315212;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
+ d="m 74.934278,230.09308 453.654042,0 0,202.04036 -453.654042,0 z"
+ id="rect5973"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffcc00;fill-opacity:1;stroke:#faf6a2;stroke-width:1.92068994;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
+ d="m 528.67583,229.34787 55.11351,-29.34622 0,190.24271 -55.11351,41.45733 z"
+ id="rect6542"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc" />
+ <rect
+ style="fill:#d38d5f;fill-opacity:1;stroke:#c48069;stroke-width:2.2674458;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect6557"
+ width="454.54535"
+ height="49.497475"
+ x="74.764442"
+ y="180.60052" />
+ <path
+ style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:0.8206054;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
+ d="m 528.30981,180.60052 55.47954,-27.27412 0,46.46702 -55.47954,29.29442 z"
+ id="rect6561"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0"
+ id="path6564"
+ d="m 528.30981,180.72501 55.03773,-27.7723 0,47.31578 -55.03773,29.8295 z"
+ style="fill:#d38d5f;fill-opacity:1;stroke:#faf6a2;stroke-width:0.82476228;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
+ inkscape:transform-center-x="-70.147578"
+ inkscape:transform-center-y="15.429055" />
+ <path
+ style="fill:#deaa87;fill-opacity:1;stroke:#faf6a2;stroke-width:2.23265362;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
+ d="m 153.39374,154.33657 430.4643,-1.01015 -54.4837,27.27411 -453.213248,0 z"
+ id="rect6568"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc" />
+ <text
+ xml:space="preserve"
+ style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="352.03815"
+ y="-190.12544"
+ id="text6623"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan6625"
+ x="352.03815"
+ y="-190.12544" /></text>
+ <text
+ xml:space="preserve"
+ style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="338.40109"
+ y="-300.73715"
+ id="text6627"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan6629"
+ x="338.40109"
+ y="-300.73715" /></text>
+ <rect
+ style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect6571"
+ width="66.670067"
+ height="60.609154"
+ x="198.49498"
+ y="119.99139" />
+ <path
+ style="fill:#ff6600;fill-opacity:1;stroke:#faf6a2;stroke-width:1.98413372;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
+ d="m 265.16503,119.45792 44.95179,-22.465406 0,57.057986 -44.95179,26.55003 z"
+ id="path6600"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ style="fill:#ff6600;fill-opacity:1;stroke:#c48069;stroke-width:1.99687159;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
+ d="m 243.06977,97.26295 66.86223,10e-7 -45.08135,22.728439 -66.3557,0 z"
+ id="path6617"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc" />
+ <text
+ xml:space="preserve"
+ style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="206.07112"
+ y="160.39748"
+ id="text6631"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan6633"
+ x="206.07112"
+ y="160.39748">API</tspan></text>
+ <rect
+ y="119.99139"
+ x="313.65237"
+ height="60.609154"
+ width="66.670067"
+ id="rect6573"
+ style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0"
+ id="path6598"
+ d="m 379.81735,119.56755 44.95179,-22.425126 0,56.955676 -44.95179,26.50243 z"
+ style="fill:#ff6600;fill-opacity:1;stroke:#faf6a2;stroke-width:1.98235416;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0"
+ id="path6615"
+ d="m 358.25117,97.26295 66.89824,10e-7 -45.10563,22.728439 -66.39143,0 z"
+ style="fill:#ff6600;fill-opacity:1;stroke:#c48069;stroke-width:1.99740911;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" />
+ <text
+ sodipodi:linespacing="125%"
+ id="text6635"
+ y="160.39748"
+ x="322.23865"
+ style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ xml:space="preserve"><tspan
+ y="160.39748"
+ x="322.23865"
+ id="tspan6637"
+ sodipodi:role="line">API</tspan></text>
+ <rect
+ style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect6575"
+ width="66.670067"
+ height="60.609154"
+ x="428.80978"
+ y="119.99139" />
+ <path
+ style="fill:#ff6600;fill-opacity:1;stroke:#faf6a2;stroke-width:1.98960423;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
+ d="m 494.97474,119.62537 44.95179,-22.589454 0,57.373054 -44.95179,26.69664 z"
+ id="rect6595"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ style="fill:#ff6600;fill-opacity:1;stroke:#c48069;stroke-width:1.99399996;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
+ d="m 473.25645,97.26295 66.67007,10e-7 -44.95179,22.728439 -66.16499,0 z"
+ id="rect6612"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc" />
+ <text
+ xml:space="preserve"
+ style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="439.41635"
+ y="159.89241"
+ id="text6639"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan6641"
+ x="439.41635"
+ y="159.89241">API</tspan></text>
+ <g
+ style="font-size:24px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ id="text6643" />
+ <text
+ xml:space="preserve"
+ style="font-size:24px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="71.720833"
+ y="95.747719"
+ id="text6648"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan6650"
+ x="71.720833"
+ y="95.747719" /></text>
+ <text
+ xml:space="preserve"
+ style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="176.77669"
+ y="216.96603"
+ id="text6652"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan6654"
+ x="176.77669"
+ y="216.96603">Network Protocol</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:36px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="233.34526"
+ y="312.93051"
+ id="text6656"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan6658"
+ x="233.34526"
+ y="312.93051">Service</tspan></text>
+ <rect
+ style="fill:#ffffff;fill-opacity:1;stroke:#faf6a2;stroke-width:2.09665918;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect6660"
+ width="66.670067"
+ height="66.609154"
+ x="216.67773"
+ y="371.51938" />
+ <rect
+ y="371.51938"
+ x="322.74374"
+ height="64.373825"
+ width="66.670067"
+ id="rect6662"
+ style="fill:#ffffff;fill-opacity:1;stroke:#faf6a2;stroke-width:2.06117821;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0"
+ id="rect6664"
+ width="66.670067"
+ height="60.609154"
+ x="423.75903"
+ y="372.52951" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0"
+ id="path6666"
+ d="m 423.61996,372.56359 67.23534,-0.62641 0,19.59587 -68.24549,41.17879 z"
+ style="fill:#ffcc00;fill-opacity:1;stroke:#faf6a2;stroke-width:0.98368376;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" />
+ <path
+ style="fill:#ffcc00;fill-opacity:1;stroke:#faf6a2;stroke-width:0.98368376;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
+ d="m 322.60471,371.55344 67.23534,0.38374 0,23.63648 -67.23534,37.13818 z"
+ id="path6668"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0"
+ id="path6670"
+ d="m 322.60471,371.55344 67.23534,0.38374 0,23.63648 -67.23534,37.13818 z"
+ style="fill:#ffcc00;fill-opacity:1;stroke:#faf6a2;stroke-width:0.98368376;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" />
+ <path
+ style="fill:#ffcc00;fill-opacity:1;stroke:#faf6a2;stroke-width:0.98368376;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
+ d="m 216.53869,371.55344 67.23534,0.38374 0,23.63648 -67.23534,37.13818 z"
+ id="path6672"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc" />
+ <text
+ xml:space="preserve"
+ style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ x="262.63965"
+ y="666.48389"
+ id="text6711"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan6713"
+ x="262.63965"
+ y="666.48389" /></text>
+ <rect
+ y="371.51938"
+ x="111.62187"
+ height="70.798637"
+ width="66.670067"
+ id="rect6721"
+ style="fill:#ffffff;fill-opacity:1;stroke:#faf6a2;stroke-width:2.1615901;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0"
+ id="path6723"
+ d="m 111.48283,370.54329 67.23534,0.38374 0,23.63648 -67.23534,37.13818 z"
+ style="fill:#ffcc00;fill-opacity:1;stroke:#faf6a2;stroke-width:0.98368376;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" />
+ </g>
+</svg>
--- /dev/null
+// house = application
+// circle (default) = service
+// box = daemon
+// diamond = library
+// black line = dependency
+// blue line = extension via plugin
+// red line = possibly useful
+// dashed = in planning
+
+// this is what we have...o
+digraph dependencies {
+splines = true;
+
+ voting [shape=house];
+ voting -> consensus;
+ voting -> identity;
+ voting -> cadet;
+ voting -> secretsharing;
+ secretsharing -> consensus;
+
+ fs [shape=house];
+ fs -> dht;
+ fs -> core;
+ fs -> datastore;
+ fs -> cadet;
+ fs -> ats;
+ fs -> block [style=dotted,color=blue];
+ fs -> identity;
+ exit [shape=box];
+ exit -> cadet;
+ exit -> tun;
+ exit -> dnsstub;
+ vpn -> cadet;
+ vpn -> regex;
+ vpn -> tun;
+ pt [shape=house];
+ pt -> cadet;
+ pt -> vpn;
+ pt -> dns;
+ pt -> dnsparser;
+ dns -> tun;
+ dns -> dnsstub;
+ zonemaster [shape=house];
+ zonemaster -> namestore;
+ zonemaster -> dht;
+ gns -> dns;
+ gns -> dht;
+ gns -> block [style=dotted,color=blue];
+ gns -> revocation;
+ gns -> vpn;
+ gns -> dnsparser;
+ gns -> dnsstub;
+ gns -> identity;
+ revocation -> core;
+ revocation -> set;
+ namestore -> identity;
+ namestore -> gnsrecord;
+ dnsparser -> gnsrecord [style=dotted,color=blue];
+ conversation -> gnsrecord [style=dotted,color=blue];
+ gns -> gnsrecord;
+ dht -> core;
+ dht -> nse;
+ dht -> block;
+ dht -> datacache;
+ dht -> peerinfo;
+ dht -> hello;
+ nse -> core;
+ regex -> block [style=dotted,color=blue];
+ block [shape=diamond];
+ datacache [shape=diamond];
+ cadet -> core [weight=2];
+ cadet -> dht;
+ cadet -> block [style=dotted,color=blue];
+ conversation [shape=house];
+ conversation -> cadet;
+ conversation -> gns;
+ conversation -> speaker;
+ conversation -> microphone;
+ speaker [shape=diamond];
+ microphone [shape=diamond];
+ regex -> dht;
+ core -> transport;
+ topology [shape=box];
+ topology -> peerinfo;
+ topology -> transport;
+ topology -> core;
+ topology -> hello;
+ hostlist [shape=box];
+ hostlist -> core;
+ hostlist -> peerinfo;
+ hostlist -> hello;
+ transport -> ats;
+ transport -> hello;
+ transport -> peerinfo;
+ transport -> nat;
+ transport -> fragmentation;
+ consensus -> set;
+ consensus -> cadet;
+ scalarproduct -> set;
+ scalarproduct -> cadet;
+ set -> cadet;
+ peerinfo -> hello;
+ fragmentation [shape=diamond];
+ hello [shape=diamond];
+ nat [shape=diamond];
+ tun [shape=diamond];
+ dnsparser [shape=diamond];
+ dnsstub [shape=diamond];
+
+ secushare [shape=house];
+ multicast;
+ psyc;
+ social -> psyc;
+ social -> gns;
+ psyc -> psycstore;
+ psycstore;
+ social;
+ secushare -> social;
+ psyc -> multicast;
+ multicast -> cadet;
+
+ rps;
+ rps -> core;
+}
--- /dev/null
+#include <unistd.h>
+#include <gnunet/platform.h>
+#include <gnunet/gnunet_util_lib.h>
+#include <gnunet/gnunet_testbed_service.h>
+#include <gnunet/gnunet_dht_service.h>
+
+#define NUM_PEERS 20
+
+static struct GNUNET_TESTBED_Operation *dht_op;
+
+static struct GNUNET_DHT_Handle *dht_handle;
+
+
+struct MyContext
+{
+ int ht_len;
+} ctxt;
+
+
+static int result;
+
+
+static void
+shutdown_task (void *cls)
+{
+ if (NULL != dht_op)
+ {
+ GNUNET_TESTBED_operation_done (dht_op);
+ dht_op = NULL;
+ dht_handle = NULL;
+ }
+ result = GNUNET_OK;
+}
+
+
+static void
+service_connect_comp (void *cls,
+ struct GNUNET_TESTBED_Operation *op,
+ void *ca_result,
+ const char *emsg)
+{
+ GNUNET_assert (op == dht_op);
+ dht_handle = ca_result;
+ // Do work here...
+ GNUNET_SCHEDULER_shutdown ();
+}
+
+
+static void *
+dht_ca (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ struct MyContext *ctxt = cls;
+
+ dht_handle = GNUNET_DHT_connect (cfg, ctxt->ht_len);
+ return dht_handle;
+}
+
+
+static void
+dht_da (void *cls, void *op_result)
+{
+ struct MyContext *ctxt = cls;
+
+ GNUNET_DHT_disconnect ((struct GNUNET_DHT_Handle *) op_result);
+ dht_handle = NULL;
+}
+
+
+static void
+test_master (void *cls,
+ struct GNUNET_TESTBED_RunHandle *h,
+ unsigned int num_peers,
+ struct GNUNET_TESTBED_Peer **peers,
+ unsigned int links_succeeded,
+ unsigned int links_failed)
+{
+ ctxt.ht_len = 10;
+ dht_op = GNUNET_TESTBED_service_connect
+ (NULL, peers[0], "dht",
+ &service_connect_comp, NULL,
+ &dht_ca, &dht_da, &ctxt);
+ GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL);
+}
+
+
+int
+main (int argc, char **argv)
+{
+ int ret;
+
+ result = GNUNET_SYSERR;
+ ret = GNUNET_TESTBED_test_run
+ ("awesome-test", "template.conf",
+ NUM_PEERS, 0LL,
+ NULL, NULL, &test_master, NULL);
+ if ( (GNUNET_OK != ret) || (GNUNET_OK != result) )
+ return 1;
+ return 0;
+}
--- /dev/null
+#include <gnunet/platform.h>
+#include <gnunet/gnunet_util_lib.h>
+
+static int ret;
+
+static void
+run (void *cls,
+ char *const *args,
+ const char *cfgfile,
+ const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ // main code here
+ ret = 0;
+}
+
+int
+main (int argc, char *const *argv)
+{
+ struct GNUNET_GETOPT_CommandLineOption options[] = {
+ GNUNET_GETOPT_OPTION_END
+ };
+ return (GNUNET_OK ==
+ GNUNET_PROGRAM_run (argc,
+ argv,
+ "binary-name",
+ gettext_noop ("binary description text"),
+ options, &run, NULL)) ? ret : 1;
+}
+
--- /dev/null
+static char *string_option;
+static int a_flag;
+
+// ...
+ struct GNUNET_GETOPT_CommandLineOption options[] = {
+ GNUNET_GETOPT_option_string ('s', "name", "SOMESTRING",
+ gettext_noop ("text describing the string_option NAME"),
+ &string_option},
+ GNUNET_GETOPT_option_flag ('f', "flag",
+ gettext_noop ("text describing the flag option"),
+ &a_flag),
+ GNUNET_GETOPT_OPTION_END
+ };
+ string_option = NULL;
+ a_flag = GNUNET_SYSERR;
+// ...
+
--- /dev/null
+struct GNUNET_MQ_MessageHandlers handlers[] = {
+ // ...
+ GNUNET_MQ_handler_end ()
+};
+struct GNUNET_MQ_Handle *mq;
+
+mq = GNUNET_CLIENT_connect (cfg,
+ "service-name",
+ handlers,
+ &error_cb,
+ NULL);
--- /dev/null
+struct GNUNET_MessageHeader
+{
+ uint16_t size GNUNET_PACKED;
+ uint16_t type GNUNET_PACKED;
+};
--- /dev/null
+struct GNUNET_MQ_Envelope *env;
+struct GNUNET_MessageHeader *msg;
+
+env = GNUNET_MQ_msg_extra (msg, payload_size, GNUNET_MY_MESSAGE_TYPE);
+memcpy (&msg[1], &payload, payload_size);
+// Send message via message queue 'mq'
+GNUNET_mq_send (mq, env);
+
--- /dev/null
+static void
+handle_fix (void *cls, const struct MyMessage *msg)
+{
+ // process 'msg'
+}
+
+static int
+check_var (void *cls, const struct MyVarMessage *msg)
+{
+ // check 'msg' is well-formed
+ return GNUNET_OK;
+}
+
+static void
+handle_var (void *cls, const struct MyVarMessage *msg)
+{
+ // process 'msg'
+}
+
+struct GNUNET_MQ_MessageHandler handlers[] = {
+ GNUNET_MQ_hd_fixed_size (fix,
+ GNUNET_MESSAGE_TYPE_MY_FIX,
+ struct MyMessage,
+ NULL),
+ GNUNET_MQ_hd_fixed_size (var,
+ GNUNET_MESSAGE_TYPE_MY_VAR,
+ struct MyVarMessage,
+ NULL),
+
+ GNUNET_MQ_handler_end ()
+};
--- /dev/null
+GNUNET_SERVICE_MAIN
+("service-name",
+ GNUNET_SERVICE_OPTION_NONE,
+ &run,
+ &client_connect_cb,
+ &client_disconnect_cb,
+ NULL,
+ GNUNET_MQ_hd_fixed_size (...),
+ GNUNET_MQ_hd_var_size (...),
+ GNUNET_MQ_handler_end ());
--- /dev/null
+static void
+run (void *cls,
+ const struct GNUNET_CONFIGURATION_Handle *c,
+ struct GNUNET_SERVICE_Handle *service)
+{
+}
+
+static void *
+client_connect_cb (void *cls,
+ struct GNUNET_SERVICE_Client *c,
+ struct GNUNET_MQ_Handle *mq)
+{
+ return c;
+}
+
+static void
+client_disconnect_cb (void *cls,
+ struct GNUNET_SERVICE_Client *c,
+ void *internal_cls)
+{
+ GNUNET_assert (c == internal_cls);
+}
--- /dev/null
+#include <gnunet/gnunet_core_service.h>
+
+struct GNUNET_CORE_Handle *
+GNUNET_CORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ void *cls,
+ GNUNET_CORE_StartupCallback init,
+ GNUNET_CORE_ConnectEventHandler connects,
+ GNUNET_CORE_DisconnectEventHandler disconnects,
+ const struct GNUNET_MQ_MessageHandler *handlers);
--- /dev/null
+void *
+connects (void *cls,
+ const struct GNUNET_PeerIdentity *peer,
+ struct GNUNET_MQ_Handle *mq)
+{
+ return mq;
+}
+
--- /dev/null
+void
+disconnects (void *cls,
+ const struct GNUNET_PeerIdentity * peer)
+{
+ /* Remove peer's identity from known peers */
+ /* Make sure no messages are sent to peer from now on */
+}
+
--- /dev/null
+#include "gnunet_peerstore_service.h"
+
+peerstore_handle = GNUNET_PEERSTORE_connect (cfg);
+
--- /dev/null
+void
+GNUNET_PEERSTORE_store_cancel (struct GNUNET_PEERSTORE_StoreContext
+ *sc);
--- /dev/null
+struct GNUNET_PEERSTORE_StoreContext *
+GNUNET_PEERSTORE_store (struct GNUNET_PEERSTORE_Handle *h,
+ const char *sub_system,
+ const struct GNUNET_PeerIdentity *peer,
+ const char *key,
+ const void *value,
+ size_t size,
+ struct GNUNET_TIME_Absolute expiry,
+ enum GNUNET_PEERSTORE_StoreOption options,
+ GNUNET_PEERSTORE_Continuation cont,
+ void *cont_cls);
+
--- /dev/null
+struct GNUNET_PEERSTORE_IterateContext *
+GNUNET_PEERSTORE_iterate (struct GNUNET_PEERSTORE_Handle *h,
+ const char *sub_system,
+ const struct GNUNET_PeerIdentity *peer,
+ const char *key,
+ struct GNUNET_TIME_Relative timeout,
+ GNUNET_PEERSTORE_Processor callback,
+ void *callback_cls);
+
--- /dev/null
+struct GNUNET_PEERSTORE_WatchContext *
+GNUNET_PEERSTORE_watch (struct GNUNET_PEERSTORE_Handle *h,
+ const char *sub_system,
+ const struct GNUNET_PeerIdentity *peer,
+ const char *key,
+ GNUNET_PEERSTORE_Processor callback,
+ void *callback_cls);
+
--- /dev/null
+void
+GNUNET_PEERSTORE_watch_cancel (struct GNUNET_PEERSTORE_WatchContext
+ *wc);
+
--- /dev/null
+void
+GNUNET_PEERSTORE_disconnect (struct GNUNET_PEERSTORE_Handle *h,
+ int sync_first);
+
--- /dev/null
+dht_handle = GNUNET_DHT_connect (cfg, parallel_requests);
+
--- /dev/null
+message_sent_cont (void *cls,
+ const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ // Request has left local node
+}
+
+struct GNUNET_DHT_PutHandle *
+GNUNET_DHT_put (struct GNUNET_DHT_Handle *handle,
+ const struct GNUNET_HashCode *key,
+ uint32_t desired_replication_level,
+ enum GNUNET_DHT_RouteOption options,
+ enum GNUNET_BLOCK_Type type,
+ size_t size,
+ const void *data,
+ struct GNUNET_TIME_Absolute exp,
+ struct GNUNET_TIME_Relative timeout,
+ GNUNET_DHT_PutContinuation cont, void *cont_cls)
+
--- /dev/null
+static void
+get_result_iterator (void *cls, struct GNUNET_TIME_Absolute expiration,
+ const struct GNUNET_HashCode *key,
+ const struct GNUNET_PeerIdentity *get_path,
+ unsigned int get_path_length,
+ const struct GNUNET_PeerIdentity *put_path,
+ unsigned int put_path_length,
+ enum GNUNET_BLOCK_Type type, size_t size,
+ const void *data)
+{
+ // Optionally:
+ GNUNET_DHT_get_stop (get_handle);
+}
+
+get_handle =
+ GNUNET_DHT_get_start (dht_handle,
+ block_type,
+ &key,
+ replication,
+ GNUNET_DHT_RO_NONE,
+ NULL,
+ 0,
+ &get_result_iterator,
+ cls)
+
--- /dev/null
+static enum GNUNET_BLOCK_EvaluationResult
+block_plugin_SERVICE_evaluate (void *cls,
+ enum GNUNET_BLOCK_Type type,
+ struct GNUNET_BlockGroup *bg,
+ const GNUNET_HashCode *query,
+ const void *xquery,
+ size_t xquery_size,
+ const void *reply_block,
+ size_t reply_block_size)
+{
+ // Verify type, block and bg
+}
+
--- /dev/null
+static int
+block_plugin_SERVICE_get_key (void *cls, enum GNUNET_BLOCK_Type type,
+ const void *block, size_t block_size,
+ struct GNUNET_HashCode *key)
+{
+ // Store the key in the key argument, return GNUNET_OK on success.
+}
+
--- /dev/null
+void *
+libgnunet_plugin_block_SERVICE_init (void *cls)
+{
+ static enum GNUNET_BLOCK_Type types[] =
+ {
+ GNUNET_BLOCK_TYPE_SERVICE_BLOCKYPE,
+ GNUNET_BLOCK_TYPE_ANY
+ };
+ struct GNUNET_BLOCK_PluginFunctions *api;
+
+ api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions);
+ api->evaluate = &block_plugin_SERICE_evaluate;
+ api->get_key = &block_plugin_SERVICE_get_key;
+ api->types = types;
+ return api;
+}
+
--- /dev/null
+void *
+libgnunet_plugin_block_SERVICE_done (void *cls)
+{
+ struct GNUNET_TRANSPORT_PluginFunctions *api = cls;
+
+ GNUNET_free (api);
+ return NULL;
+}
+
--- /dev/null
+ plugindir = $(libdir)/gnunet
+
+ plugin_LTLIBRARIES = \
+ libgnunet_plugin_block_ext.la
+ libgnunet_plugin_block_ext_la_SOURCES = \
+ plugin_block_ext.c
+ libgnunet_plugin_block_ext_la_LIBADD = \
+ $(prefix)/lib/libgnunethello.la \
+ $(prefix)/lib/libgnunetblock.la \
+ $(prefix)/lib/libgnunetutil.la
+ libgnunet_plugin_block_ext_la_LDFLAGS = \
+ $(GN_PLUGIN_LDFLAGS)
+ libgnunet_plugin_block_ext_la_DEPENDENCIES = \
+ $(prefix)/lib/libgnunetblock.la
+
--- /dev/null
+static void
+get_callback (void *cls,
+ enum GNUNET_DHT_RouteOption options,
+ enum GNUNET_BLOCK_Type type,
+ uint32_t hop_count,
+ uint32_t desired_replication_level,
+ unsigned int path_length,
+ const struct GNUNET_PeerIdentity *path,
+ const struct GNUNET_HashCode * key)
+{
+}
+
+
+static void
+get_resp_callback (void *cls,
+ enum GNUNET_BLOCK_Type type,
+ const struct GNUNET_PeerIdentity *get_path,
+ unsigned int get_path_length,
+ const struct GNUNET_PeerIdentity *put_path,
+ unsigned int put_path_length,
+ struct GNUNET_TIME_Absolute exp,
+ const struct GNUNET_HashCode * key,
+ const void *data,
+ size_t size)
+{
+}
+
+
+static void
+put_callback (void *cls,
+ enum GNUNET_DHT_RouteOption options,
+ enum GNUNET_BLOCK_Type type,
+ uint32_t hop_count,
+ uint32_t desired_replication_level,
+ unsigned int path_length,
+ const struct GNUNET_PeerIdentity *path,
+ struct GNUNET_TIME_Absolute exp,
+ const struct GNUNET_HashCode * key,
+ const void *data,
+ size_t size)
+{
+}
+
+
+monitor_handle = GNUNET_DHT_monitor_start (dht_handle,
+ block_type,
+ key,
+ &get_callback,
+ &get_resp_callback,
+ &put_callback,
+ cls);
+
+++ /dev/null
-@c The GNU Free Documentation License.
-@center Version 1.3, 3 November 2008
-
-@c This file is intended to be included within another document,
-@c hence no sectioning command or @node.
-
-@display
-Copyright @copyright{} 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
-@uref{http://fsf.org/}
-
-Everyone is permitted to copy and distribute verbatim copies
-of this license document, but changing it is not allowed.
-@end display
-
-@enumerate 0
-@item
-PREAMBLE
-
-The purpose of this License is to make a manual, textbook, or other
-functional and useful document @dfn{free} in the sense of freedom: to
-assure everyone the effective freedom to copy and redistribute it,
-with or without modifying it, either commercially or noncommercially.
-Secondarily, this License preserves for the author and publisher a way
-to get credit for their work, while not being considered responsible
-for modifications made by others.
-
-This License is a kind of ``copyleft'', which means that derivative
-works of the document must themselves be free in the same sense. It
-complements the GNU General Public License, which is a copyleft
-license designed for free software.
-
-We have designed this License in order to use it for manuals for free
-software, because free software needs free documentation: a free
-program should come with manuals providing the same freedoms that the
-software does. But this License is not limited to software manuals;
-it can be used for any textual work, regardless of subject matter or
-whether it is published as a printed book. We recommend this License
-principally for works whose purpose is instruction or reference.
-
-@item
-APPLICABILITY AND DEFINITIONS
-
-This License applies to any manual or other work, in any medium, that
-contains a notice placed by the copyright holder saying it can be
-distributed under the terms of this License. Such a notice grants a
-world-wide, royalty-free license, unlimited in duration, to use that
-work under the conditions stated herein. The ``Document'', below,
-refers to any such manual or work. Any member of the public is a
-licensee, and is addressed as ``you''. You accept the license if you
-copy, modify or distribute the work in a way requiring permission
-under copyright law.
-
-A ``Modified Version'' of the Document means any work containing the
-Document or a portion of it, either copied verbatim, or with
-modifications and/or translated into another language.
-
-A ``Secondary Section'' is a named appendix or a front-matter section
-of the Document that deals exclusively with the relationship of the
-publishers or authors of the Document to the Document's overall
-subject (or to related matters) and contains nothing that could fall
-directly within that overall subject. (Thus, if the Document is in
-part a textbook of mathematics, a Secondary Section may not explain
-any mathematics.) The relationship could be a matter of historical
-connection with the subject or with related matters, or of legal,
-commercial, philosophical, ethical or political position regarding
-them.
-
-The ``Invariant Sections'' are certain Secondary Sections whose titles
-are designated, as being those of Invariant Sections, in the notice
-that says that the Document is released under this License. If a
-section does not fit the above definition of Secondary then it is not
-allowed to be designated as Invariant. The Document may contain zero
-Invariant Sections. If the Document does not identify any Invariant
-Sections then there are none.
-
-The ``Cover Texts'' are certain short passages of text that are listed,
-as Front-Cover Texts or Back-Cover Texts, in the notice that says that
-the Document is released under this License. A Front-Cover Text may
-be at most 5 words, and a Back-Cover Text may be at most 25 words.
-
-A ``Transparent'' copy of the Document means a machine-readable copy,
-represented in a format whose specification is available to the
-general public, that is suitable for revising the document
-straightforwardly with generic text editors or (for images composed of
-pixels) generic paint programs or (for drawings) some widely available
-drawing editor, and that is suitable for input to text formatters or
-for automatic translation to a variety of formats suitable for input
-to text formatters. A copy made in an otherwise Transparent file
-format whose markup, or absence of markup, has been arranged to thwart
-or discourage subsequent modification by readers is not Transparent.
-An image format is not Transparent if used for any substantial amount
-of text. A copy that is not ``Transparent'' is called ``Opaque''.
-
-Examples of suitable formats for Transparent copies include plain
-ASCII without markup, Texinfo input format, La@TeX{} input
-format, SGML or XML using a publicly available
-DTD, and standard-conforming simple HTML,
-PostScript or PDF designed for human modification. Examples
-of transparent image formats include PNG, XCF and
-JPG. Opaque formats include proprietary formats that can be
-read and edited only by proprietary word processors, SGML or
-XML for which the DTD and/or processing tools are
-not generally available, and the machine-generated HTML,
-PostScript or PDF produced by some word processors for
-output purposes only.
-
-The ``Title Page'' means, for a printed book, the title page itself,
-plus such following pages as are needed to hold, legibly, the material
-this License requires to appear in the title page. For works in
-formats which do not have any title page as such, ``Title Page'' means
-the text near the most prominent appearance of the work's title,
-preceding the beginning of the body of the text.
-
-The ``publisher'' means any person or entity that distributes copies
-of the Document to the public.
-
-A section ``Entitled XYZ'' means a named subunit of the Document whose
-title either is precisely XYZ or contains XYZ in parentheses following
-text that translates XYZ in another language. (Here XYZ stands for a
-specific section name mentioned below, such as ``Acknowledgements'',
-``Dedications'', ``Endorsements'', or ``History''.) To ``Preserve the Title''
-of such a section when you modify the Document means that it remains a
-section ``Entitled XYZ'' according to this definition.
-
-The Document may include Warranty Disclaimers next to the notice which
-states that this License applies to the Document. These Warranty
-Disclaimers are considered to be included by reference in this
-License, but only as regards disclaiming warranties: any other
-implication that these Warranty Disclaimers may have is void and has
-no effect on the meaning of this License.
-
-@item
-VERBATIM COPYING
-
-You may copy and distribute the Document in any medium, either
-commercially or noncommercially, provided that this License, the
-copyright notices, and the license notice saying this License applies
-to the Document are reproduced in all copies, and that you add no other
-conditions whatsoever to those of this License. You may not use
-technical measures to obstruct or control the reading or further
-copying of the copies you make or distribute. However, you may accept
-compensation in exchange for copies. If you distribute a large enough
-number of copies you must also follow the conditions in section 3.
-
-You may also lend copies, under the same conditions stated above, and
-you may publicly display copies.
-
-@item
-COPYING IN QUANTITY
-
-If you publish printed copies (or copies in media that commonly have
-printed covers) of the Document, numbering more than 100, and the
-Document's license notice requires Cover Texts, you must enclose the
-copies in covers that carry, clearly and legibly, all these Cover
-Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
-the back cover. Both covers must also clearly and legibly identify
-you as the publisher of these copies. The front cover must present
-the full title with all words of the title equally prominent and
-visible. You may add other material on the covers in addition.
-Copying with changes limited to the covers, as long as they preserve
-the title of the Document and satisfy these conditions, can be treated
-as verbatim copying in other respects.
-
-If the required texts for either cover are too voluminous to fit
-legibly, you should put the first ones listed (as many as fit
-reasonably) on the actual cover, and continue the rest onto adjacent
-pages.
-
-If you publish or distribute Opaque copies of the Document numbering
-more than 100, you must either include a machine-readable Transparent
-copy along with each Opaque copy, or state in or with each Opaque copy
-a computer-network location from which the general network-using
-public has access to download using public-standard network protocols
-a complete Transparent copy of the Document, free of added material.
-If you use the latter option, you must take reasonably prudent steps,
-when you begin distribution of Opaque copies in quantity, to ensure
-that this Transparent copy will remain thus accessible at the stated
-location until at least one year after the last time you distribute an
-Opaque copy (directly or through your agents or retailers) of that
-edition to the public.
-
-It is requested, but not required, that you contact the authors of the
-Document well before redistributing any large number of copies, to give
-them a chance to provide you with an updated version of the Document.
-
-@item
-MODIFICATIONS
-
-You may copy and distribute a Modified Version of the Document under
-the conditions of sections 2 and 3 above, provided that you release
-the Modified Version under precisely this License, with the Modified
-Version filling the role of the Document, thus licensing distribution
-and modification of the Modified Version to whoever possesses a copy
-of it. In addition, you must do these things in the Modified Version:
-
-@enumerate A
-@item
-Use in the Title Page (and on the covers, if any) a title distinct
-from that of the Document, and from those of previous versions
-(which should, if there were any, be listed in the History section
-of the Document). You may use the same title as a previous version
-if the original publisher of that version gives permission.
-
-@item
-List on the Title Page, as authors, one or more persons or entities
-responsible for authorship of the modifications in the Modified
-Version, together with at least five of the principal authors of the
-Document (all of its principal authors, if it has fewer than five),
-unless they release you from this requirement.
-
-@item
-State on the Title page the name of the publisher of the
-Modified Version, as the publisher.
-
-@item
-Preserve all the copyright notices of the Document.
-
-@item
-Add an appropriate copyright notice for your modifications
-adjacent to the other copyright notices.
-
-@item
-Include, immediately after the copyright notices, a license notice
-giving the public permission to use the Modified Version under the
-terms of this License, in the form shown in the Addendum below.
-
-@item
-Preserve in that license notice the full lists of Invariant Sections
-and required Cover Texts given in the Document's license notice.
-
-@item
-Include an unaltered copy of this License.
-
-@item
-Preserve the section Entitled ``History'', Preserve its Title, and add
-to it an item stating at least the title, year, new authors, and
-publisher of the Modified Version as given on the Title Page. If
-there is no section Entitled ``History'' in the Document, create one
-stating the title, year, authors, and publisher of the Document as
-given on its Title Page, then add an item describing the Modified
-Version as stated in the previous sentence.
-
-@item
-Preserve the network location, if any, given in the Document for
-public access to a Transparent copy of the Document, and likewise
-the network locations given in the Document for previous versions
-it was based on. These may be placed in the ``History'' section.
-You may omit a network location for a work that was published at
-least four years before the Document itself, or if the original
-publisher of the version it refers to gives permission.
-
-@item
-For any section Entitled ``Acknowledgements'' or ``Dedications'', Preserve
-the Title of the section, and preserve in the section all the
-substance and tone of each of the contributor acknowledgements and/or
-dedications given therein.
-
-@item
-Preserve all the Invariant Sections of the Document,
-unaltered in their text and in their titles. Section numbers
-or the equivalent are not considered part of the section titles.
-
-@item
-Delete any section Entitled ``Endorsements''. Such a section
-may not be included in the Modified Version.
-
-@item
-Do not retitle any existing section to be Entitled ``Endorsements'' or
-to conflict in title with any Invariant Section.
-
-@item
-Preserve any Warranty Disclaimers.
-@end enumerate
-
-If the Modified Version includes new front-matter sections or
-appendices that qualify as Secondary Sections and contain no material
-copied from the Document, you may at your option designate some or all
-of these sections as invariant. To do this, add their titles to the
-list of Invariant Sections in the Modified Version's license notice.
-These titles must be distinct from any other section titles.
-
-You may add a section Entitled ``Endorsements'', provided it contains
-nothing but endorsements of your Modified Version by various
-parties---for example, statements of peer review or that the text has
-been approved by an organization as the authoritative definition of a
-standard.
-
-You may add a passage of up to five words as a Front-Cover Text, and a
-passage of up to 25 words as a Back-Cover Text, to the end of the list
-of Cover Texts in the Modified Version. Only one passage of
-Front-Cover Text and one of Back-Cover Text may be added by (or
-through arrangements made by) any one entity. If the Document already
-includes a cover text for the same cover, previously added by you or
-by arrangement made by the same entity you are acting on behalf of,
-you may not add another; but you may replace the old one, on explicit
-permission from the previous publisher that added the old one.
-
-The author(s) and publisher(s) of the Document do not by this License
-give permission to use their names for publicity for or to assert or
-imply endorsement of any Modified Version.
-
-@item
-COMBINING DOCUMENTS
-
-You may combine the Document with other documents released under this
-License, under the terms defined in section 4 above for modified
-versions, provided that you include in the combination all of the
-Invariant Sections of all of the original documents, unmodified, and
-list them all as Invariant Sections of your combined work in its
-license notice, and that you preserve all their Warranty Disclaimers.
-
-The combined work need only contain one copy of this License, and
-multiple identical Invariant Sections may be replaced with a single
-copy. If there are multiple Invariant Sections with the same name but
-different contents, make the title of each such section unique by
-adding at the end of it, in parentheses, the name of the original
-author or publisher of that section if known, or else a unique number.
-Make the same adjustment to the section titles in the list of
-Invariant Sections in the license notice of the combined work.
-
-In the combination, you must combine any sections Entitled ``History''
-in the various original documents, forming one section Entitled
-``History''; likewise combine any sections Entitled ``Acknowledgements'',
-and any sections Entitled ``Dedications''. You must delete all
-sections Entitled ``Endorsements.''
-
-@item
-COLLECTIONS OF DOCUMENTS
-
-You may make a collection consisting of the Document and other documents
-released under this License, and replace the individual copies of this
-License in the various documents with a single copy that is included in
-the collection, provided that you follow the rules of this License for
-verbatim copying of each of the documents in all other respects.
-
-You may extract a single document from such a collection, and distribute
-it individually under this License, provided you insert a copy of this
-License into the extracted document, and follow this License in all
-other respects regarding verbatim copying of that document.
-
-@item
-AGGREGATION WITH INDEPENDENT WORKS
-
-A compilation of the Document or its derivatives with other separate
-and independent documents or works, in or on a volume of a storage or
-distribution medium, is called an ``aggregate'' if the copyright
-resulting from the compilation is not used to limit the legal rights
-of the compilation's users beyond what the individual works permit.
-When the Document is included in an aggregate, this License does not
-apply to the other works in the aggregate which are not themselves
-derivative works of the Document.
-
-If the Cover Text requirement of section 3 is applicable to these
-copies of the Document, then if the Document is less than one half of
-the entire aggregate, the Document's Cover Texts may be placed on
-covers that bracket the Document within the aggregate, or the
-electronic equivalent of covers if the Document is in electronic form.
-Otherwise they must appear on printed covers that bracket the whole
-aggregate.
-
-@item
-TRANSLATION
-
-Translation is considered a kind of modification, so you may
-distribute translations of the Document under the terms of section 4.
-Replacing Invariant Sections with translations requires special
-permission from their copyright holders, but you may include
-translations of some or all Invariant Sections in addition to the
-original versions of these Invariant Sections. You may include a
-translation of this License, and all the license notices in the
-Document, and any Warranty Disclaimers, provided that you also include
-the original English version of this License and the original versions
-of those notices and disclaimers. In case of a disagreement between
-the translation and the original version of this License or a notice
-or disclaimer, the original version will prevail.
-
-If a section in the Document is Entitled ``Acknowledgements'',
-``Dedications'', or ``History'', the requirement (section 4) to Preserve
-its Title (section 1) will typically require changing the actual
-title.
-
-@item
-TERMINATION
-
-You may not copy, modify, sublicense, or distribute the Document
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense, or distribute it is void, and
-will automatically terminate your rights under this License.
-
-However, if you cease all violation of this License, then your license
-from a particular copyright holder is reinstated (a) provisionally,
-unless and until the copyright holder explicitly and finally
-terminates your license, and (b) permanently, if the copyright holder
-fails to notify you of the violation by some reasonable means prior to
-60 days after the cessation.
-
-Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
-Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License. If your rights have been terminated and not permanently
-reinstated, receipt of a copy of some or all of the same material does
-not give you any rights to use it.
-
-@item
-FUTURE REVISIONS OF THIS LICENSE
-
-The Free Software Foundation may publish new, revised versions
-of the GNU Free Documentation License from time to time. Such new
-versions will be similar in spirit to the present version, but may
-differ in detail to address new problems or concerns. See
-@uref{http://www.gnu.org/copyleft/}.
-
-Each version of the License is given a distinguishing version number.
-If the Document specifies that a particular numbered version of this
-License ``or any later version'' applies to it, you have the option of
-following the terms and conditions either of that specified version or
-of any later version that has been published (not as a draft) by the
-Free Software Foundation. If the Document does not specify a version
-number of this License, you may choose any version ever published (not
-as a draft) by the Free Software Foundation. If the Document
-specifies that a proxy can decide which future versions of this
-License can be used, that proxy's public statement of acceptance of a
-version permanently authorizes you to choose that version for the
-Document.
-
-@item
-RELICENSING
-
-``Massive Multiauthor Collaboration Site'' (or ``MMC Site'') means any
-World Wide Web server that publishes copyrightable works and also
-provides prominent facilities for anybody to edit those works. A
-public wiki that anybody can edit is an example of such a server. A
-``Massive Multiauthor Collaboration'' (or ``MMC'') contained in the
-site means any set of copyrightable works thus published on the MMC
-site.
-
-``CC-BY-SA'' means the Creative Commons Attribution-Share Alike 3.0
-license published by Creative Commons Corporation, a not-for-profit
-corporation with a principal place of business in San Francisco,
-California, as well as future copyleft versions of that license
-published by that same organization.
-
-``Incorporate'' means to publish or republish a Document, in whole or
-in part, as part of another Document.
-
-An MMC is ``eligible for relicensing'' if it is licensed under this
-License, and if all works that were first published under this License
-somewhere other than this MMC, and subsequently incorporated in whole
-or in part into the MMC, (1) had no cover texts or invariant sections,
-and (2) were thus incorporated prior to November 1, 2008.
-
-The operator of an MMC Site may republish an MMC contained in the site
-under CC-BY-SA on the same site at any time before August 1, 2009,
-provided the MMC is eligible for relicensing.
-
-@end enumerate
-
-@page
-@heading ADDENDUM: How to use this License for your documents
-
-To use this License in a document you have written, include a copy of
-the License in the document and put the following copyright and
-license notices just after the title page:
-
-@smallexample
-@group
- Copyright (C) @var{year} @var{your name}.
- Permission is granted to copy, distribute and/or modify this document
- under the terms of the GNU Free Documentation License, Version 1.3
- or any later version published by the Free Software Foundation;
- with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
- Texts. A copy of the license is included in the section entitled ``GNU
- Free Documentation License''.
-@end group
-@end smallexample
-
-If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
-replace the ``with@dots{}Texts.''@: line with this:
-
-@smallexample
-@group
- with the Invariant Sections being @var{list their titles}, with
- the Front-Cover Texts being @var{list}, and with the Back-Cover Texts
- being @var{list}.
-@end group
-@end smallexample
-
-If you have Invariant Sections without Cover Texts, or some other
-combination of the three, merge those two alternatives to suit the
-situation.
-
-If your document contains nontrivial examples of program code, we
-recommend releasing these examples in parallel under your choice of
-free software license, such as the GNU General Public License,
-to permit their use in free software.
-
-@c Local Variables:
-@c ispell-local-pdict: "ispell-dict"
-@c End:
+++ /dev/null
-\input texinfo
-@c %**start of header
-@setfilename gnunet-c-tutorial.info
-@documentencoding UTF-8
-@settitle GNUnet C Tutorial
-@exampleindent 2
-@c %**end of header
-
-@c including 'version.texi' makes makeinfo throw errors.
-@include version2.texi
-
-@copying
-Copyright @copyright{} 2001-2017 GNUnet e.V.
-
-Permission is granted to copy, distribute and/or modify this document
-under the terms of the GNU Free Documentation License, Version 1.3 or
-any later version published by the Free Software Foundation; with no
-Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A
-copy of the license is included in the section entitled ``GNU Free
-Documentation License''.
-
-A copy of the license is also available from the Free Software
-Foundation Web site at @url{http://www.gnu.org/licenses/fdl.html}.
-
-Alternately, this document is also available under the General
-Public License, version 3 or later, as published by the Free Software
-Foundation. A copy of the license is included in the section entitled
-``GNU General Public License''.
-
-A copy of the license is also available from the Free Software
-Foundation Web site at @url{http://www.gnu.org/licenses/gpl.html}.
-@end copying
-
-@dircategory Tutorial
-@direntry
-* GNUnet-C-Tutorial: (gnunet-c-tutorial). C Tutorial for GNunet
-@end direntry
-
-
-@titlepage
-@title GNUnet C Tutorial
-@subtitle A Tutorial for GNUnet @value{VERSION} (C version)
-@author The GNUnet Developers
-
-@page
-@vskip 0pt plus 1filll
-
-@insertcopying
-@end titlepage
-
-@contents
-
-@c **** TODO
-@c 1. Update content?
-@c 2. Either reference main documentation or
-@c 3. Merge this into main documentation
-
-@node Top
-@top Introduction
-
-This tutorials explains how to install GNUnet on a
-GNU/Linux system and gives an introduction on how
-GNUnet can be used to develop a Peer-to-Peer application.
-Detailed installation instructions for
-various operating systems and a detailed list of all
-dependencies can be found on our website at
-@uref{https://gnunet.org/installation} and in our
-Reference Documentation (GNUnet Handbook).
-
-Please read this tutorial carefully since every single step is
-important and do not hesitate to contact the GNUnet team if you have
-any questions or problems! Check here how to contact the GNUnet
-team: @uref{https://gnunet.org/contact_information}
-
-@menu
-
-* Installing GNUnet:: Installing GNUnet
-* Introduction to GNUnet Architecture:: Introduction to GNUnet Architecture
-* First Steps with GNUnet:: First Steps with GNUnet
-* Developing Applications:: Developing Applications
-
-@detailmenu
- --- The Detailed Node Listing ---
-
-Installing GNUnet
-
-* Obtaining a stable version::
-* Installing Build Tool Chain and Dependencies::
-* Obtaining the latest version from Git::
-* Compiling and Installing GNUnet::
-* Common Issues - Check your GNUnet installation::
-
-Introduction to GNUnet Architecture
-
-First Steps with GNUnet
-
-* Configure your peer::
-* Start a peer::
-* Monitor a peer::
-* Starting Two Peers by Hand::
-* Starting Peers Using the Testbed Service::
-
-Developing Applications
-
-* gnunet-ext::
-* Adapting the Template::
-* Writing a Client Application::
-* Writing a Service::
-* Interacting directly with other Peers using the CORE Service::
-* Storing peer-specific data using the PEERSTORE service::
-* Using the DHT::
-* Debugging with gnunet-arm::
-
-@end detailmenu
-@end menu
-
-@node Installing GNUnet
-@chapter Installing GNUnet
-
-First of all you have to install a current version of GNUnet.
-You can download a tarball of a stable version from GNU FTP mirrors
-or obtain the latest development version from our Git repository.
-
-Most of the time you should prefer to download the stable version
-since with the latest development version things can be broken,
-functionality can be changed or tests can fail. You should only use
-the development version if you know that you require a certain
-feature or a certain issue has been fixed since the last release.
-
-@menu
-* Obtaining a stable version::
-* Installing Build Tool Chain and Dependencies::
-* Obtaining the latest version from Git::
-* Compiling and Installing GNUnet::
-* Common Issues - Check your GNUnet installation::
-@end menu
-
-@node Obtaining a stable version
-@section Obtaining a stable version
-
-Download the tarball from
-@indicateurl{https://ftp.gnu.org/gnu/gnunet/gnunet-@value{VERSION}.tar.gz}.
-
-Make sure to download the associated @file{.sig} file and to verify the
-authenticity of the tarball against it, like this:
-
-@example
-$ wget https://ftp.gnu.org/gnu/gnunet/gnunet-@value{VERSION}.tar.gz.sig
-$ gpg --verify-files gnunet-@value{VERSION}.tar.gz.sig
-@end example
-
-@noindent
-If this command fails because you do not have the required public key,
-then you need to run this command to import it:
-
-@example
-$ gpg --keyserver keys.gnupg.net --recv-keys 48426C7E
-@end example
-
-@noindent
-and rerun the @code{gpg --verify-files} command.
-
-Now you can extract the tarball and rename the resulting
-directory to @i{gnunet} which we will be using in the
-remainder of this document.
-
-@example
-$ tar xvzf gnunet-@value{VERSION}.tar.gz
-$ mv gnunet-@value{VERSION} gnunet
-$ cd gnunet
-@end example
-
-@noindent
-However, please note that stable versions can be very outdated.
-As a developer you are @b{strongly} encouraged to use the version
-from @uref{https://gnunet.org/git/, git}.
-
-@node Installing Build Tool Chain and Dependencies
-@section Installing Build Tool Chain and Dependencies
-
-To successfully compile GNUnet you need the tools to build GNUnet and
-the required dependencies. Please have a look at
-@uref{https://gnunet.org/dependencies} for a list of required dependencies
-and @uref{https://gnunet.org/generic_installation} for specific
-instructions for your operating system. Please check the notes at
-the end of the configure process about required dependencies.
-
-For GNUnet bootstrapping support and the http(s) plugin you should
-install @uref{https://gnunet.org/gnurl, libgnurl}.
-For the filesharing service you should install at least one of the
-datastore backends. MySQL, SQlite and PostgreSQL are supported.
-
-@node Obtaining the latest version from Git
-@section Obtaining the latest version from Git
-
-The latest development version can obtained from our Git repository.
-To obtain the code you need Git installed and checkout the repository
-using:
-
-@example
-$ git clone https://gnunet.org/git/gnunet
-@end example
-
-@noindent
-After cloning the repository you have to execute the @file{bootstrap}
-script in the directory:
-
-@example
-$ cd gnunet ; ./bootstrap
-@end example
-
-@noindent
-The remainder of this tutorial assumes that you have the Git branch
-``master'' checked out.
-
-@node Compiling and Installing GNUnet
-@section Compiling and Installing GNUnet
-
-First, you need to install at least libgnupgerror 1.27 and
-libgcrypt 1.7.6.
-
-@example
-$ export GNUPGFTP="https://www.gnupg.org/ftp/gcrypt"
-$ wget $GNUPGFTP/libgpg-error/libgpg-error-1.27.tar.bz2
-$ tar xf libgpg-error-1.27.tar.bz2
-$ cd libgpg-error-1.27
-$ ./configure
-$ sudo make install
-$ cd ..
-@end example
-
-@example
-$ export GNUPGFTP="https://www.gnupg.org/ftp/gcrypt"
-$ wget $GNUPGFTP/libgcrypt/libgcrypt-1.7.6.tar.bz2
-$ tar xf libgcrypt-1.7.6.tar.bz2
-$ cd libgcrypt-1.7.6
-$ ./configure
-$ sudo make install
-$ cd ..
-@end example
-
-@menu
-* Installation::
-@end menu
-
-@node Installation
-@subsection Installation
-Assuming all dependencies are installed, the following commands will
-compile and install GNUnet in your home directory. You can specify the
-directory where GNUnet will be installed by changing the
-@code{--prefix} value when calling @command{./configure}. If
-you do not specifiy a prefix, GNUnet is installed in the directory
-@file{/usr/local}. When developing new applications you may want
-to enable verbose logging by adding @code{--enable-logging=verbose}:
-
-@example
-$ ./configure --prefix=$PREFIX --enable-logging
-$ make
-$ make install
-@end example
-
-@noindent
-After installing GNUnet you have to add your GNUnet installation
-to your path environmental variable. In addition you have to
-create the @file{.config} directory in your home directory
-(unless it already exists) where GNUnet stores its data and an
-empty GNUnet configuration file:
-
-@example
-$ export PATH=$PATH:$PREFIX/bin
-$ echo export PATH=$PREFIX/bin:\\$PATH >> ~/.bashrc
-$ mkdir ~/.config/
-$ touch ~/.config/gnunet.conf
-@end example
-
-@node Common Issues - Check your GNUnet installation
-@section Common Issues - Check your GNUnet installation
-
-You should check your installation to ensure that installing GNUnet
-was successful up to this point. You should be able to access GNUnet's
-binaries and run GNUnet's self check.
-
-@example
-$ which gnunet-arm
-@end example
-
-@noindent
-should return $PREFIX/bin/gnunet-arm. It should be located in your
-GNUnet installation and the output should not be empty.
-If you see an output like:
-
-@example
-$ which gnunet-arm
-@end example
-
-@noindent
-check your PATH variable to ensure GNUnet's @file{bin} directory is
-included.
-
-GNUnet provides tests for all of its subcomponents. Run
-
-@example
-$ make check
-@end example
-
-@noindent
-to execute tests for all components. @command{make check} traverses all
-subdirectories in @file{src}. For every subdirectory you should
-get a message like this:
-
-@example
-make[2]: Entering directory `/home/$USER/gnunet/contrib'
-PASS: test_gnunet_prefix
-=============
-1 test passed
-=============
-@end example
-
-@node Introduction to GNUnet Architecture
-@chapter Introduction to GNUnet Architecture
-
-GNUnet is organized in layers and services. Each service is composed of a
-main service implementation and a client library for other programs to use
-the service's functionality, described by an API.
-@c This approach is shown in
-@c FIXME: enable this once the commented block below works:
-@c figure~\ref fig:service.
-Some services provide an additional command line tool to enable the user
-to interact with the service.
-
-Very often it is other GNUnet services that will use these APIs to build
-the higher layers of GNUnet on top of the lower ones. Each layer expands
-or extends the functionality of the service below (for instance, to build
-a mesh on top of a DHT).
-@c FXIME: See comment above.
-@c See figure ~\ref fig:interaction for an illustration of this approach.
-
-@c ** @image filename[, width[, height[, alttext[, extension]]]]
-@c FIXME: Texlive (?) 20112 makes the assumption that this means
-@c 'images/OBJECTNAME.txt' but later versions of it (2017) use this
-@c syntax as described below.
-@c TODO: Checkout the makedoc script Guile uses.
-
-@image{images/gnunet-tutorial-service,,5in,Service with API and network protocol,.png}
-
-@image{images/gnunet-tutorial-system,,5in,The layered system architecture of GNUnet,.png}
-
-@c \begin{figure}[!h]
-@c \begin{center}
-@c % \begin{subfigure}
-@c \begin{subfigure}[b]{0.3\textwidth}
-@c \centering
-@c \includegraphics[width=\textwidth]{figs/Service.pdf}
-@c \caption{Service with API and network protocol}
-@c \label{fig:service}
-@c \end{subfigure}
-@c ~~~~~~~~~~
-@c \begin{subfigure}[b]{0.3\textwidth}
-@c \centering
-@c \includegraphics[width=\textwidth]{figs/System.pdf}
-@c \caption{Service interaction}
-@c \label{fig:interaction}
-@c \end{subfigure}
-@c \end{center}
-@c \caption{GNUnet's layered system architecture}
-@c \end{figure}
-
-The main service implementation runs as a standalone process in the
-operating system and the client code runs as part of the client program,
-so crashes of a client do not affect the service process or other clients.
-The service and the clients communicate via a message protocol to be
-defined and implemented by the programmer.
-
-@node First Steps with GNUnet
-@chapter First Steps with GNUnet
-
-@menu
-* Configure your peer::
-* Start a peer::
-* Monitor a peer::
-* Starting Two Peers by Hand::
-* Starting Peers Using the Testbed Service::
-@end menu
-
-@node Configure your peer
-@section Configure your peer
-
-First of all we need to configure your peer. Each peer is started with
-a configuration containing settings for GNUnet itself and its services.
-This configuration is based on the default configuration shipped with
-GNUnet and can be modified. The default configuration is located in the
-@file{$PREFIX/share/gnunet/config.d} directory. When starting a peer, you
-can specify a customized configuration using the the @command{-c} command
-line switch when starting the ARM service and all other services. When
-using a modified configuration the default values are loaded and only
-values specified in the configuration file will replace the default
-values.
-
-Since we want to start additional peers later, we need some modifications
-from the default configuration. We need to create a separate service
-home and a file containing our modifications for this peer:
-
-@example
-$ mkdir ~/gnunet1/
-$ touch peer1.conf
-@end example
-
-@noindent
-Now add the following lines to @file{peer1.conf} to use this directory.
-For simplified usage we want to prevent the peer to connect to the GNUnet
-network since this could lead to confusing output. This modifications
-will replace the default settings:
-
-@example
-[PATHS]
-# Use this directory to store GNUnet data
-GNUNET_HOME = ~/gnunet1/
-[hostlist]
-# prevent bootstrapping
-SERVERS =
-@end example
-
-@node Start a peer
-@section Start a peer
-Each GNUnet instance (called peer) has an identity (peer ID) based on a
-cryptographic public private key pair. The peer ID is the printable hash
-of the public key.
-
-GNUnet services are controlled by a master service, the so called
-@dfn{Automatic Restart Manager} (ARM). ARM starts, stops and even
-restarts services automatically or on demand when a client connects.
-You interact with the ARM service using the @command{gnunet-arm} tool.
-GNUnet can then be started with @command{gnunet-arm -s} and stopped with
-@command{gnunet-arm -e}. An additional service not automatically started
-can be started using @command{gnunet-arm -i <service name>} and stopped
-using @command{gnunet-arm -k <servicename>}.
-
-Once you have started your peer, you can use many other GNUnet commands
-to interact with it. For example, you can run:
-
-@example
-$ gnunet-peerinfo -s
-@end example
-
-@noindent
-to obtain the public key of your peer.
-
-You should see an output containing the peer ID similar to:
-
-@example
-I am peer `0PA02UVRKQTS2C .. JL5Q78F6H0B1ACPV1CJI59MEQUMQCC5G'.
-@end example
-
-@node Monitor a peer
-@section Monitor a peer
-
-In this section, we will monitor the behaviour of our peer's DHT
-service with respect to a specific key. First we will start
-GNUnet and then start the DHT service and use the DHT monitor tool
-to monitor the PUT and GET commands we issue ussing the
-@command{gnunet-dht-put} and @command{gnunet-dht-get} commands.
-Using the ``monitor'' line given below, you can observe the behavior
-of your own peer's DHT with respect to the specified KEY:
-
-@example
-# start gnunet with all default services:
-$ gnunet-arm -c ~/peer1.conf -s
-# start DHT service:
-$ gnunet-arm -c ~/peer1.conf -i dht
-$ cd ~/gnunet/src/dht;
-$ ./gnunet-dht-monitor -c ~/peer1.conf -k KEY
-@end example
-
-@noindent
-Now open a separate terminal and change again to
-the @file{gnunet/src/dht} directory:
-
-@example
-$ cd ~/gnunet/src/dht
-# put VALUE under KEY in the DHT:
-$ ./gnunet-dht-put -c ~/peer1.conf -k KEY -d VALUE
-# get key KEY from the DHT:
-$ ./gnunet/src/dht/gnunet-dht-get -c ~/peer1.conf -k KEY
-# print statistics about current GNUnet state:
-$ gnunet-statistics -c ~/peer1.conf
-# print statistics about DHT service:
-$ gnunet-statistics -c ~/peer1.conf -s dht
-@end example
-
-@node Starting Two Peers by Hand
-@section Starting Two Peers by Hand
-
-This section describes how to start two peers on the same machine by hand.
-The process is rather painful, but the description is somewhat
-instructive. In practice, you might prefer the automated method
-(@pxref{Starting Peers Using the Testbed Service}).
-
-@menu
-* Setup a second peer::
-* Start the second peer and connect the peers::
-* How to connect manually::
-@end menu
-
-@node Setup a second peer
-@subsection Setup a second peer
-We will now start a second peer on your machine.
-For the second peer, you will need to manually create a modified
-configuration file to avoid conflicts with ports and directories.
-A peers configuration file is by default located
-in @file{~/.gnunet/gnunet.conf}. This file is typically very short
-or even empty as only the differences to the defaults need to be
-specified. The defaults are located in many files in the
-@file{$PREFIX/share/gnunet/config.d} directory.
-
-To configure the second peer, use the files
-@file{$PREFIX/share/gnunet/config.d} as a template for your main
-configuration file:
-
-@example
-$ cat $PREFIX/share/gnunet/config.d/*.conf > peer2.conf
-@end example
-
-@noindent
-Now you have to edit @file{peer2.conf} and change:
-
-@itemize
-@item @code{GNUNET\_TEST\_HOME} under @code{PATHS}
-@item Every (uncommented) value for ``@code{PORT}'' (add 10000) in any
-section (the option may be commented out if @code{PORT} is
-prefixed by "\#", in this case, UNIX domain sockets are used
-and the PORT option does not need to be touched)
-@item Every value for ``@code{UNIXPATH}'' in any section
-(e.g. by adding a "-p2" suffix)
-@end itemize
-
-to a fresh, unique value. Make sure that the PORT numbers stay
-below 65536. From now on, whenever you interact with the second peer,
-you need to specify @command{-c peer2.conf} as an additional
-command line argument.
-
-Now, generate the 2nd peer's private key:
-
-@example
-$ gnunet-peerinfo -s -c peer2.conf
-@end example
-
-@noindent
-This may take a while, generate entropy using your keyboard or mouse
-as needed. Also, make sure the output is different from the
-gnunet-peerinfo output for the first peer (otherwise you made an
-error in the configuration).
-
-@node Start the second peer and connect the peers
-@subsection Start the second peer and connect the peers
-
-Then, you can start a second peer using:
-
-@example
-$ gnunet-arm -c peer2.conf -s
-$ gnunet-arm -c peer2.conf -i dht
-$ ~/gnunet/src/dht/gnunet-dht-put -c peer2.conf -k KEY -d VALUE
-$ ~/gnunet/src/dht/gnunet-dht-get -c peer2.conf -k KEY
-@end example
-
-If you want the two peers to connect, you have multiple options:
-
-@itemize
-@item UDP neighbour discovery (automatic)
-@item Setup a bootstrap server
-@item Connect manually
-@end itemize
-
-To setup peer 1 as bootstrapping server change the configuration of
-the first one to be a hostlist server by adding the following lines to
-@file{peer1.conf} to enable bootstrapping server:
-
-@example
-[hostlist]
-OPTIONS = -p
-@end example
-
-@noindent
-Then change @file{peer2.conf} and replace the ``@code{SERVERS}''
-line in the ``@code{[hostlist]}'' section with
-``@code{http://localhost:8080/}''. Restart both peers using:
-
-@example
-# stop first peer
-$ gnunet-arm -c peer1.conf -e
-# start first peer
-$ gnunet-arm -c peer1.conf -s
-# start second peer
-$ gnunet-arm -c peer2.conf -s
-@end example
-
-@noindent
-Note that if you start your peers without changing these settings, they
-will use the ``global'' hostlist servers of the GNUnet P2P network and
-likely connect to those peers. At that point, debugging might become
-tricky as you're going to be connected to many more peers and would
-likely observe traffic and behaviors that are not explicitly controlled
-by you.
-
-@node How to connect manually
-@subsection How to connect manually
-
-If you want to use the @code{peerinfo} tool to connect your
-peers, you should:
-
-@itemize
-@item Set @code{FORCESTART = NO} in section @code{hostlist}
-(to not connect to the global GNUnet)
-@item Start both peers running @command{gnunet-arm -c peer1.conf -s}
-and @command{gnunet-arm -c peer2.conf -s}
-@item Get @code{HELLO} message of the first peer running
-@command{gnunet-peerinfo -c peer1.conf -g}
-@item Give the output to the second peer by running
-@command{gnunet-peerinfo -c peer2.conf -p '<output>'}
-@end itemize
-
-Check that they are connected using @command{gnunet-core -c peer1.conf},
-which should give you the other peer's peer identity:
-
-@example
-$ gnunet-core -c peer1.conf
-Peer `9TVUCS8P5A7ILLBGO6 [...shortened...] 1KNBJ4NGCHP3JPVULDG'
-@end example
-
-@node Starting Peers Using the Testbed Service
-@section Starting Peers Using the Testbed Service
-@c \label{sec:testbed}
-
-GNUnet's testbed service is used for testing scenarios where
-a number of peers are to be started. The testbed can manage peers
-on a single host or on multiple hosts in a distributed fashion.
-On a single affordable computer, it should be possible to run
-around tens of peers without drastically increasing the load on the
-system.
-
-The testbed service can be access through its API
-@file{include/gnunet\_testbed\_service.h}. The API provides many
-routines for managing a group of peers. It also provides a helper
-function @code{GNUNET\_TESTBED\_test\_run()} to quickly setup a
-minimalistic testing environment on a single host.
-
-This function takes a configuration file which will be used as a
-template configuration for the peers. The testbed takes care of
-modifying relevant options in the peers' configuration such as
-@code{SERVICEHOME}, @code{PORT}, @code{UNIXPATH} to unique values
-so that peers run without running into conflicts. It also checks
-and assigns the ports in configurations only if they are free.
-
-Additionally, the testbed service also reads its options from the
-same configuration file. Various available options and details
-about them can be found in the testbed default configuration file
-@file{src/testbed/testbed.conf}.
-
-With the testbed API, a sample test case can be structured as follows:
-
-@example
-@verbatiminclude testbed_test.c
-@end example
-
-@noindent
-The source code for the above listing can be found at
-@uref{https://gnunet.org/git/gnunet.git/tree/doc/testbed_test.c}
-or in the @file{doc/} folder of your repository check-out.
-After installing GNUnet, the above source code can be compiled as:
-
-@example
-$ export CPPFLAGS="-I/path/to/gnunet/headers"
-$ export LDFLAGS="-L/path/to/gnunet/libraries"
-$ gcc $CPPFLAGS $LDFLAGS -o testbed-test testbed_test.c \
- -lgnunettestbed -lgnunetdht -lgnunetutil
-# Generate (empty) configuration
-$ touch template.conf
-# run it (press CTRL-C to stop)
-$ ./testbed-test
-@end example
-
-@noindent
-The @code{CPPFLAGS} and @code{LDFLAGS} are necessary if GNUnet
-is installed into a different directory other than @file{/usr/local}.
-
-All of testbed API's peer management functions treat management
-actions as operations and return operation handles. It is expected
-that the operations begin immediately, but they may get delayed (to
-balance out load on the system). The program using the API then has
-to take care of marking the operation as ``done'' so that its
-associated resources can be freed immediately and other waiting
-operations can be executed. Operations will be canceled if they are
-marked as ``done'' before their completion.
-
-An operation is treated as completed when it succeeds or fails.
-Completion of an operation is either conveyed as events through
-@i{controller event callback} or through respective operation
-completion callbacks. In functions which support completion
-notification through both controller event callback and operation
-completion callback, first the controller event callback will be
-called. If the operation is not marked as done in that callback
-or if the callback is given as NULL when creating the operation,
-the operation completion callback will be called. The API
-documentation shows which event are to be expected in the
-controller event notifications. It also documents any exceptional
-behaviour.
-
-Once the peers are started, test cases often need to connect
-some of the peers' services. Normally, opening a connect to
-a peer's service requires the peer's configuration. While using
-testbed, the testbed automatically generates per-peer configuration.
-Accessing those configurations directly through file system is
-discouraged as their locations are dynamically created and will be
-different among various runs of testbed. To make access to these
-configurations easy, testbed API provides the function
-@code{GNUNET\_TESTBED\_service\_connect()}. This function fetches
-the configuration of a given peer and calls the @i{Connect Adapter}.
-In the example code, it is the @code{dht\_ca}. A connect adapter is
-expected to open the connection to the needed service by using the
-provided configuration and return the created service connection handle.
-Successful connection to the needed service is signaled through
-@code{service\_connect\_comp\_cb}.
-
-A dual to connect adapter is the @i{Disconnect Adapter}. This callback
-is called after the connect adapter has been called when the operation
-from @code{GNUNET\_TESTBED\_service\_connect()} is marked as ``done''.
-It has to disconnect from the service with the provided service
-handle (@code{op\_result}).
-
-Exercise: Find out how many peers you can run on your system.
-
-Exercise: Find out how to create a 2D torus topology by changing the
-options in the configuration file.
-See @uref{https://gnunet.org/supported-topologies}, then use the
-DHT API to store and retrieve values in the network.
-
-@node Developing Applications
-@chapter Developing Applications
-
-@menu
-* gnunet-ext::
-* Adapting the Template::
-* Writing a Client Application::
-* Writing a Service::
-* Interacting directly with other Peers using the CORE Service::
-* Storing peer-specific data using the PEERSTORE service::
-* Using the DHT::
-* Debugging with gnunet-arm::
-@end menu
-
-@node gnunet-ext
-@section gnunet-ext
-To develop a new peer-to-peer application or to extend GNUnet we provide
-a template build system for writing GNUnet extensions in C. It can be
-obtained as follows:
-
-@example
-$ git clone https://gnunet.org/git/gnunet-ext
-$ cd gnunet-ext/
-$ ./bootstrap
-$ ./configure --prefix=$PREFIX --with-gnunet=$PREFIX
-$ make
-$ make install
-$ make check
-@end example
-
-@noindent
-The GNUnet ext template includes examples and a working buildsystem
-for a new GNUnet service. A common GNUnet service consists of the
-following parts which will be discussed in detail in the remainder
-of this document. The functionality of a GNUnet service is implemented in:
-
-@itemize
-@item the GNUnet service (gnunet-ext/src/ext/gnunet-service-ext.c)
-@item the client API (gnunet-ext/src/ext/ext_api.c)
-@item the client application using the service API
-(gnunet-ext/src/ext/gnunet-ext.c)
-@end itemize
-
-The interfaces for these entities are defined in:
-
-@itemize
-@item client API interface (gnunet-ext/src/ext/ext.h)
-@item the service interface (gnunet-ext/src/include/gnunet_service_SERVICE.h)
-@item the P2P protocol (gnunet-ext/src/include/gnunet_protocols_ext.h)
-@end itemize
-
-
-In addition the ext systems provides:
-
-@itemize
-@item a test testing the API (gnunet-ext/src/ext/test_ext_api.c)
-@item a configuration template for the service
-(gnunet-ext/src/ext/ext.conf.in)
-@end itemize
-
-@node Adapting the Template
-@section Adapting the Template
-
-The first step for writing any extension with a new service is to
-ensure that the @file{ext.conf.in} file contains entries for the
-@code{UNIXPATH}, @code{PORT} and @code{BINARY} for the service in a
-section named after the service.
-
-If you want to adapt the template rename the @file{ext.conf.in} to
-match your services name, you have to modify the @code{AC\_OUTPUT}
-section in @file{configure.ac} in the @file{gnunet-ext} root.
-
-@node Writing a Client Application
-@section Writing a Client Application
-
-When writing any client application (for example, a command-line
-tool), the basic structure is to start with the
-@code{GNUNET\_PROGRAM\_run} function. This function will parse
-command-line options, setup the scheduler and then invoke the
-@code{run} function (with the remaining non-option arguments)
-and a handle to the parsed configuration (and the configuration
-file name that was used, which is typically not needed):
-
-@example
-@verbatiminclude tutorial-examples/001.c
-@end example
-
-@menu
-* Handling command-line options::
-* Writing a Client Library::
-* Writing a user interface::
-@end menu
-
-@node Handling command-line options
-@subsection Handling command-line options
-
-Options can then be added easily by adding global variables and
-expanding the @code{options} array. For example, the following would
-add a string-option and a binary flag (defaulting to @code{NULL} and
-@code{GNUNET\_NO} respectively):
-
-@example
-@verbatiminclude tutorial-examples/002.c
-@end example
-
-Issues such as displaying some helpful text describing options using
-the @code{--help} argument and error handling are taken care of when
-using this approach. Other @code{GNUNET\_GETOPT\_}-functions can be used
-to obtain integer value options, increment counters, etc. You can
-even write custom option parsers for special circumstances not covered
-by the available handlers. To check if an argument was specified by the
-user you initialize the variable with a specific value (e.g. NULL for
-a string and GNUNET\_SYSERR for a integer) and check after parsing
-happened if the values were modified.
-
-Inside the @code{run} method, the program would perform the
-application-specific logic, which typically involves initializing and
-using some client library to interact with the service. The client
-library is supposed to implement the IPC whereas the service provides
-more persistent P2P functions.
-
-Exercise: Add a few command-line options and print them inside
-of @code{run}. What happens if the user gives invalid arguments?
-
-@node Writing a Client Library
-@subsection Writing a Client Library
-
-The first and most important step in writing a client library is to
-decide on an API for the library. Typical API calls include
-connecting to the service, performing application-specific requests
-and cleaning up. Many examples for such service APIs can be found
-in the @file{gnunet/src/include/gnunet\_*\_service.h} files.
-
-Then, a client-service protocol needs to be designed. This typically
-involves defining various message formats in a header that will be
-included by both the service and the client library (but is otherwise
-not shared and hence located within the service's directory and not
-installed by @command{make install}). Each message must start with a
-@code{struct GNUNET\_MessageHeader} and must be shorter than 64k. By
-convention, all fields in IPC (and P2P) messages must be in big-endian
-format (and thus should be read using @code{ntohl} and similar
-functions and written using @code{htonl} and similar functions).
-Unique message types must be defined for each message struct in the
-@file{gnunet\_protocols.h} header (or an extension-specific include
-file).
-
-@menu
-* Connecting to the Service::
-* Sending messages::
-* Receiving Replies from the Service::
-@end menu
-
-@node Connecting to the Service
-@subsubsection Connecting to the Service
-
-Before a client library can implement the application-specific protocol
-with the service, a connection must be created:
-
-@example
-@verbatiminclude tutorial-examples/003.c
-@end example
-
-@noindent
-As a result a @code{GNUNET\_MQ\_Handle} is returned
-which can to used henceforth to transmit messages to the service.
-The complete MQ API can be found in @file{gnunet\_mq\_lib.h}.
-The @code{hanlders} array in the example above is incomplete.
-Here is where you will define which messages you expect to
-receive from the service, and which functions handle them.
-The @code{error\_cb} is a function that is to be called whenever
-there are errors communicating with the service.
-
-@node Sending messages
-@subsubsection Sending messages
-
-In GNUnet, messages are always sent beginning with a
-@code{struct GNUNET\_MessageHeader} in big endian format.
-This header defines the size and the type of the
-message, the payload follows after this header.
-
-@example
-@verbatiminclude tutorial-examples/004.c
-@end example
-
-@noindent
-Existing message types are defined in @file{gnunet\_protocols.h}.
-A common way to create a message is with an envelope:
-
-@example
-@verbatiminclude tutorial-examples/005.c
-@end example
-
-@noindent
-Exercise: Define a message struct that includes a 32-bit
-unsigned integer in addition to the standard GNUnet MessageHeader.
-Add a C struct and define a fresh protocol number for your message.
-Protocol numbers in gnunet-ext are defined
-in @file{gnunet-ext/src/include/gnunet_protocols_ext.h}
-
-Exercise: Find out how you can determine the number of messages
-in a message queue.
-
-Exercise: Find out how you can determine when a message you
-have queued was actually transmitted.
-
-Exercise: Define a helper function to transmit a 32-bit
-unsigned integer (as payload) to a service using some given client
-handle.
-
-@node Receiving Replies from the Service
-@subsubsection Receiving Replies from the Service
-
-Clients can receive messages from the service using the handlers
-specified in the @code{handlers} array we specified when connecting
-to the service. Entries in the the array are usually created using
-one of two macros, depending on whether the message is fixed size
-or variable size. Variable size messages are managed using two
-callbacks, one to check that the message is well-formed, the other
-to actually process the message. Fixed size messages are fully
-checked by the MQ-logic, and thus only need to provide the handler
-to process the message. Note that the prefixes @code{check\_}
-and @code{handle\_} are mandatory.
-
-@example
-@verbatiminclude tutorial-examples/006.c
-@end example
-
-@noindent
-Exercise: Expand your helper function to receive a response message
-(for example, containing just the @code{struct GNUnet MessageHeader}
-without any payload). Upon receiving the service's response, you
-should call a callback provided to your helper function's API.
-
-Exercise: Figure out where you can pass values to the
-closures (@code{cls}).
-
-@node Writing a user interface
-@subsection Writing a user interface
-
-Given a client library, all it takes to access a service now is to
-combine calls to the client library with parsing command-line
-options.
-
-Exercise: Call your client API from your @code{run()} method in your
-client application to send a request to the service. For example,
-send a 32-bit integer value based on a number given at the
-command-line to the service.
-
-@node Writing a Service
-@section Writing a Service
-
-Before you can test the client you've written so far, you'll
-need to also implement the corresponding service.
-
-@menu
-* Code Placement::
-* Starting a Service::
-@end menu
-
-@node Code Placement
-@subsection Code Placement
-
-New services are placed in their own subdirectory under
-@file{gnunet/src}. This subdirectory should contain the API
-implementation file @file{SERVICE\_api.c}, the description of
-the client-service protocol @file{SERVICE.h} and P2P protocol
-@file{SERVICE\_protocol.h}, the implementation of the service itself
-@file{gnunet-service-SERVICE.h} and several files for tests,
-including test code and configuration files.
-
-@node Starting a Service
-@subsection Starting a Service
-
-The key API definition for creating a service is the
-@code{GNUNET\_SERVICE\_MAIN} macro:
-
-@example
-@verbatiminclude tutorial-examples/007.c
-@end example
-
-@noindent
-In addition to the service name and flags, the macro takes three
-functions, typically called @code{run}, @code{client\_connect\_cb} and
-@code{client\_disconnect\_cb} as well as an array of message handlers
-that will be called for incoming messages from clients.
-
-A minimal version of the three central service funtions would look
-like this:
-
-@example
-@verbatiminclude tutorial-examples/008.c
-@end example
-
-@noindent
-Exercise: Write a stub service that processes no messages at all
-in your code. Create a default configuration for it, integrate it
-with the build system and start the service from
-@command{gnunet-service-arm} using @command{gnunet-arm -i NAME}.
-
-Exercise: Figure out how to set the closure (@code{cls}) for handlers
-of a service.
-
-Exercise: Figure out how to send messages from the service back to the
-client.
-
-Each handler function in the service @b{must} eventually (possibly in some
-asynchronous continuation) call
-@code{GNUNET\_SERVICE\_client\_continue()}. Only after this call
-additional messages from the same client may
-be processed. This way, the service can throttle processing messages
-from the same client.
-
-Exercise: Change the service to ``handle'' the message from your
-client (for now, by printing a message). What happens if you
-forget to call @code{GNUNET\_SERVICE\_client\_continue()}?
-
-@node Interacting directly with other Peers using the CORE Service
-@section Interacting directly with other Peers using the CORE Service
-
-FIXME: This section still needs to be updated to the lastest API!
-
-One of the most important services in GNUnet is the @code{CORE} service
-managing connections between peers and handling encryption between peers.
-
-One of the first things any service that extends the P2P protocol
-typically does is connect to the @code{CORE} service using:
-
-@example
-@verbatiminclude tutorial-examples/009.c
-@end example
-
-@menu
-* New P2P connections::
-* Receiving P2P Messages::
-* Sending P2P Messages::
-* End of P2P connections::
-@end menu
-
-@node New P2P connections
-@subsection New P2P connections
-
-Before any traffic with a different peer can be exchanged, the peer must
-be known to the service. This is notified by the @code{CORE}
-@code{connects} callback, which communicates the identity of the new
-peer to the service:
-
-@example
-@verbatiminclude tutorial-examples/010.c
-@end example
-
-@noindent
-Note that whatever you return from @code{connects} is given as the
-@i{cls} argument to the message handlers for messages from
-the respective peer.
-
-Exercise: Create a service that connects to the @code{CORE}. Then
-start (and connect) two peers and print a message once your connect
-callback is invoked.
-
-@node Receiving P2P Messages
-@subsection Receiving P2P Messages
-
-To receive messages from @code{CORE}, you pass the desired
-@i{handlers} to the @code{GNUNET\_CORE\_connect()} function,
-just as we showed for services.
-
-It is your responsibility to process messages fast enough or
-to implement flow control. If an application does not process
-CORE messages fast enough, CORE will randomly drop messages
-to not keep a very long queue in memory.
-
-Exercise: Start one peer with a new service that has a message
-handler and start a second peer that only has your ``old'' service
-without message handlers. Which ``connect'' handlers are invoked when
-the two peers are connected? Why?
-
-@node Sending P2P Messages
-@subsection Sending P2P Messages
-
-You can transmit messages to other peers using the @i{mq} you were
-given during the @code{connect} callback. Note that the @i{mq}
-automatically is released upon @code{disconnect} and that you must
-not use it afterwards.
-
-It is your responsibility to not over-fill the message queue, GNUnet
-will send the messages roughly in the order given as soon as possible.
-
-Exercise: Write a service that upon connect sends messages as
-fast as possible to the other peer (the other peer should run a
-service that ``processes'' those messages). How fast is the
-transmission? Count using the STATISTICS service on both ends. Are
-messages lost? How can you transmit messages faster? What happens if
-you stop the peer that is receiving your messages?
-
-@node End of P2P connections
-@subsection End of P2P connections
-
-If a message handler returns @code{GNUNET\_SYSERR}, the remote
-peer shuts down or there is an unrecoverable network
-disconnection, CORE notifies the service that the peer disconnected.
-After this notification no more messages will be received from the
-peer and the service is no longer allowed to send messages to the peer.
-The disconnect callback looks like the following:
-
-@example
-@verbatiminclude tutorial-examples/011.c
-@end example
-
-@noindent
-Exercise: Fix your service to handle peer disconnects.
-
-@node Storing peer-specific data using the PEERSTORE service
-@section Storing peer-specific data using the PEERSTORE service
-
-GNUnet's PEERSTORE service offers a persistorage for arbitrary
-peer-specific data. Other GNUnet services can use the PEERSTORE
-to store, retrieve and monitor data records. Each data record
-stored with PEERSTORE contains the following fields:
-
-@itemize
-@item subsystem: Name of the subsystem responsible for the record.
-@item peerid: Identity of the peer this record is related to.
-@item key: a key string identifying the record.
-@item value: binary record value.
-@item expiry: record expiry date.
-@end itemize
-
-The first step is to start a connection to the PEERSTORE service:
-@example
-@verbatiminclude tutorial-examples/012.c
-@end example
-
-The service handle @code{peerstore_handle} will be needed for
-all subsequent PEERSTORE operations.
-
-@menu
-* Storing records::
-* Retrieving records::
-* Monitoring records::
-* Disconnecting from PEERSTORE::
-@end menu
-
-@node Storing records
-@subsection Storing records
-
-To store a new record, use the following function:
-
-@example
-@verbatiminclude tutorial-examples/013.c
-@end example
-
-@noindent
-The @code{options} parameter can either be
-@code{GNUNET_PEERSTORE_STOREOPTION_MULTIPLE} which means that multiple
-values can be stored under the same key combination
-(subsystem, peerid, key), or @code{GNUNET_PEERSTORE_STOREOPTION_REPLACE}
-which means that PEERSTORE will replace any existing values under the
-given key combination (subsystem, peerid, key) with the new given value.
-
-The continuation function @code{cont} will be called after the store
-request is successfully sent to the PEERSTORE service. This does not
-guarantee that the record is successfully stored, only that it was
-received by the service.
-
-The @code{GNUNET_PEERSTORE_store} function returns a handle to the store
-operation. This handle can be used to cancel the store operation only
-before the continuation function is called:
-
-@example
-@verbatiminclude tutorial-examples/013.1.c
-@end example
-
-@node Retrieving records
-@subsection Retrieving records
-
-To retrieve stored records, use the following function:
-
-@example
-@verbatiminclude tutorial-examples/014.c
-@end example
-
-@noindent
-The values of @code{peer} and @code{key} can be @code{NULL}. This
-allows the iteration over values stored under any of the following
-key combinations:
-
-@itemize
-@item (subsystem)
-@item (subsystem, peerid)
-@item (subsystem, key)
-@item (subsystem, peerid, key)
-@end itemize
-
-The @code{callback} function will be called once with each retrieved
-record and once more with a @code{NULL} record to signal the end of
-results.
-
-The @code{GNUNET_PEERSTORE_iterate} function returns a handle to the
-iterate operation. This handle can be used to cancel the iterate
-operation only before the callback function is called with a
-@code{NULL} record.
-
-@node Monitoring records
-@subsection Monitoring records
-
-PEERSTORE offers the functionality of monitoring for new records
-stored under a specific key combination (subsystem, peerid, key).
-To start the monitoring, use the following function:
-
-@example
-@verbatiminclude tutorial-examples/015.c
-@end example
-
-@noindent
-Whenever a new record is stored under the given key combination,
-the @code{callback} function will be called with this new
-record. This will continue until the connection to the PEERSTORE
-service is broken or the watch operation is canceled:
-
-@example
-@verbatiminclude tutorial-examples/016.c
-@end example
-
-@node Disconnecting from PEERSTORE
-@subsection Disconnecting from PEERSTORE
-
-When the connection to the PEERSTORE service is no longer needed,
-disconnect using the following function:
-
-@example
-@verbatiminclude tutorial-examples/017.c
-@end example
-
-@noindent
-If the @code{sync_first} flag is set to @code{GNUNET_YES},
-the API will delay the disconnection until all store requests
-are received by the PEERSTORE service. Otherwise, it will
-disconnect immediately.
-
-@node Using the DHT
-@section Using the DHT
-
-The DHT allows to store data so other peers in the P2P network can
-access it and retrieve data stored by any peers in the network.
-This section will explain how to use the DHT. Of course, the first
-thing to do is to connect to the DHT service:
-
-@example
-@verbatiminclude tutorial-examples/018.c
-@end example
-
-@noindent
-The second parameter indicates how many requests in parallel to expect.
-It is not a hard limit, but a good approximation will make the DHT more
-efficient.
-
-@menu
-* Storing data in the DHT::
-* Obtaining data from the DHT::
-* Implementing a block plugin::
-* Monitoring the DHT::
-@end menu
-
-@node Storing data in the DHT
-@subsection Storing data in the DHT
-Since the DHT is a dynamic environment (peers join and leave frequently)
-the data that we put in the DHT does not stay there indefinitely. It is
-important to ``refresh'' the data periodically by simply storing it
-again, in order to make sure other peers can access it.
-
-The put API call offers a callback to signal that the PUT request has been
-sent. This does not guarantee that the data is accessible to others peers,
-or even that is has been stored, only that the service has requested to
-a neighboring peer the retransmission of the PUT request towards its final
-destination. Currently there is no feedback about whether or not the data
-has been sucessfully stored or where it has been stored. In order to
-improve the availablilty of the data and to compensate for possible
-errors, peers leaving and other unfavorable events, just make several
-PUT requests!
-
-@example
-@verbatiminclude tutorial-examples/019.c
-@end example
-
-@noindent
-Exercise: Store a value in the DHT periodically to make sure it
-is available over time. You might consider using the function
-@code{GNUNET\_SCHEDULER\_add\_delayed} and call
-@code{GNUNET\_DHT\_put} from inside a helper function.
-
-@node Obtaining data from the DHT
-@subsection Obtaining data from the DHT
-
-As we saw in the previous example, the DHT works in an asynchronous mode.
-Each request to the DHT is executed ``in the background'' and the API
-calls return immediately. In order to receive results from the DHT, the
-API provides a callback. Once started, the request runs in the service,
-the service will try to get as many results as possible (filtering out
-duplicates) until the timeout expires or we explicitly stop the request.
-It is possible to give a ``forever'' timeout with
-@code{GNUNET\_TIME\_UNIT\_FOREVER\_REL}.
-
-If we give a route option @code{GNUNET\_DHT\_RO\_RECORD\_ROUTE}
-the callback will get a list of all the peers the data has travelled,
-both on the PUT path and on the GET path.
-
-@example
-@verbatiminclude tutorial-examples/020.c
-@end example
-
-@noindent
-Exercise: Store a value in the DHT and after a while retrieve it.
-Show the IDs of all the peers the requests have gone through.
-In order to convert a peer ID to a string, use the function
-@code{GNUNET\_i2s}. Pay attention to the route option parameters
-in both calls!
-
-@node Implementing a block plugin
-@subsection Implementing a block plugin
-
-In order to store data in the DHT, it is necessary to provide a block
-plugin. The DHT uses the block plugin to ensure that only well-formed
-requests and replies are transmitted over the network.
-
-The block plugin should be put in a file @file{plugin\_block\_SERVICE.c}
-in the service's respective directory. The
-mandatory functions that need to be implemented for a block plugin are
-described in the following sections.
-
-@menu
-* Validating requests and replies::
-* Deriving a key from a reply::
-* Initialization of the plugin::
-* Shutdown of the plugin::
-* Integration of the plugin with the build system::
-@end menu
-
-@node Validating requests and replies
-@subsubsection Validating requests and replies
-
-The evaluate function should validate a reply or a request. It returns
-a @code{GNUNET\_BLOCK\_EvaluationResult}, which is an enumeration. All
-possible answers are in @file{gnunet\_block\_lib.h}. The function will
-be called with a @code{reply\_block} argument of @code{NULL} for
-requests. Note that depending on how @code{evaluate} is called, only
-some of the possible return values are valid. The specific meaning of
-the @code{xquery} argument is application-specific. Applications that
-do not use an extended query should check that the @code{xquery\_size}
-is zero. The block group is typically used to filter duplicate
-replies.
-
-@example
-@verbatiminclude tutorial-examples/021.c
-@end example
-
-@noindent
-Note that it is mandatory to detect duplicate replies in this function
-and return the respective status code. Duplicate detection is
-typically done using the Bloom filter block group provided by
-@file{libgnunetblockgroup.so}. Failure to do so may cause replies to
-circle in the network.
-
-@node Deriving a key from a reply
-@subsubsection Deriving a key from a reply
-
-The DHT can operate more efficiently if it is possible to derive a key
-from the value of the corresponding block. The @code{get\_key}
-function is used to obtain the key of a block --- for example, by
-means of hashing. If deriving the key is not possible, the function
-should simply return @code{GNUNET\_SYSERR} (the DHT will still work
-just fine with such blocks).
-
-@example
-@verbatiminclude tutorial-examples/022.c
-@end example
-
-@node Initialization of the plugin
-@subsubsection Initialization of the plugin
-
-The plugin is realized as a shared C library. The library must export
-an initialization function which should initialize the plugin. The
-initialization function specifies what block types the plugin cares
-about and returns a struct with the functions that are to be used for
-validation and obtaining keys (the ones just defined above).
-
-@example
-@verbatiminclude tutorial-examples/023.c
-@end example
-
-@node Shutdown of the plugin
-@subsubsection Shutdown of the plugin
-
-Following GNUnet's general plugin API concept, the plugin must
-export a second function for cleaning up. It usually does very
-little.
-
-@example
-@verbatiminclude tutorial-examples/024.c
-@end example
-
-@node Integration of the plugin with the build system
-@subsubsection Integration of the plugin with the build system
-
-In order to compile the plugin, the @file{Makefile.am} file for the
-service SERVICE should contain a rule similar to this:
-@c Actually this is a Makefile not C. But the whole structure of examples
-@c must be improved.
-
-@example
-@verbatiminclude tutorial-examples/025.c
-@end example
-
-@noindent
-Exercise: Write a block plugin that accepts all queries
-and all replies but prints information about queries and replies
-when the respective validation hooks are called.
-
-@node Monitoring the DHT
-@subsection Monitoring the DHT
-
-It is possible to monitor the functioning of the local
-DHT service. When monitoring the DHT, the service will
-alert the monitoring program of any events, both started
-locally or received for routing from another peer.
-The are three different types of events possible: a
-GET request, a PUT request or a response (a reply to a GET).
-
-Since the different events have different associated data,
-the API gets 3 different callbacks (one for each message type)
-and optional type and key parameters, to allow for filtering of
-messages. When an event happens, the appropiate callback is
-called with all the information about the event.
-
-@example
-@verbatiminclude tutorial-examples/026.c
-@end example
-
-@node Debugging with gnunet-arm
-@section Debugging with gnunet-arm
-
-Even if services are managed by @command{gnunet-arm}, you can
-start them with @command{gdb} or @command{valgrind}. For
-example, you could add the following lines to your
-configuration file to start the DHT service in a @command{gdb}
-session in a fresh @command{xterm}:
-
-@example
-[dht]
-PREFIX=xterm -e gdb --args
-@end example
-
-@noindent
-Alternatively, you can stop a service that was started via
-ARM and run it manually:
-
-@example
-$ gnunet-arm -k dht
-$ gdb --args gnunet-service-dht -L DEBUG
-$ valgrind gnunet-service-dht -L DEBUG
-@end example
-
-@noindent
-Assuming other services are well-written, they will automatically
-re-integrate the restarted service with the peer.
-
-GNUnet provides a powerful logging mechanism providing log
-levels @code{ERROR}, @code{WARNING}, @code{INFO} and @code{DEBUG}.
-The current log level is configured using the @code{$GNUNET_FORCE_LOG}
-environmental variable. The @code{DEBUG} level is only available if
-@command{--enable-logging=verbose} was used when running
-@command{configure}. More details about logging can be found under
-@uref{https://gnunet.org/logging}.
-
-You should also probably enable the creation of core files, by setting
-@code{ulimit}, and echo'ing @code{1} into
-@file{/proc/sys/kernel/core\_uses\_pid}. Then you can investigate the
-core dumps with @command{gdb}, which is often the fastest method to
-find simple errors.
-
-Exercise: Add a memory leak to your service and obtain a trace
-pointing to the leak using @command{valgrind} while running the service
-from @command{gnunet-service-arm}.
-
-@bye
+++ /dev/null
-\input texinfo
-@c -*-texinfo-*-
-
-@c %**start of header
-@setfilename gnunet.info
-@documentencoding UTF-8
-@settitle GNUnet Reference Manual
-@exampleindent 2
-@c %**end of header
-
-@include version.texi
-
-@c Set Versions which might be used in more than one place:
-@set GNUNET-DIST-URL https://ftp.gnu.org/gnu/gnunet/
-@set GNUNET-VERSION 0.10.1
-@set GNURL-VERSION-CURRENT 7.55.1
-@set GNURL-DIST-URL https://gnunet.org/sites/default/files/
-@c @set OPENPGP-SIGNING-KEY-ID
-
-@copying
-Copyright @copyright{} 2001-2017 GNUnet e.V.
-
-Permission is granted to copy, distribute and/or modify this document
-under the terms of the GNU Free Documentation License, Version 1.3 or
-any later version published by the Free Software Foundation; with no
-Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A
-copy of the license is included in the section entitled ``GNU Free
-Documentation License''.
-
-A copy of the license is also available from the Free Software
-Foundation Web site at @url{http://www.gnu.org/licenses/fdl.html}.
-
-Alternately, this document is also available under the General
-Public License, version 3 or later, as published by the Free Software
-Foundation. A copy of the license is included in the section entitled
-``GNU General Public License''.
-
-A copy of the license is also available from the Free Software
-Foundation Web site at @url{http://www.gnu.org/licenses/gpl.html}.
-@end copying
-
-@c TODO: Improve this and improve https://directory.fsf.org/wiki/Gnunet
-
-@dircategory Networking
-@direntry
-* GNUnet: (gnunet). Framework for secure peer-to-peer networking
-@end direntry
-
-@titlepage
-@title GNUnet Reference Manual
-@subtitle Installing, configuring, using and contributing to GNUnet
-@author The GNUnet Developers
-
-@page
-@vskip 0pt plus 1filll
-Edition @value{EDITION} @*
-@value{UPDATED} @*
-
-@insertcopying
-@end titlepage
-
-@summarycontents
-@contents
-
-@node Top
-@top Contributing to GNUnet
-
-
-This document describes GNUnet version @value{VERSION}.
-
-
-GNUnet is a @uref{http://www.gnu.org/, GNU} package.
-All code contributions must thus be put under the
-@uref{http://www.gnu.org/copyleft/gpl.html, GNU Public License (GPL)}.
-All documentation should be put under FSF approved licenses
-(see @uref{http://www.gnu.org/copyleft/fdl.html, fdl}).
-
-By submitting documentation, translations, comments and other
-content to this website you automatically grant the right to publish
-code under the GNU Public License and documentation under either or
-both the GNU Public License or the GNU Free Documentation License.
-When contributing to the GNUnet project, GNU standards and the
-@uref{http://www.gnu.org/philosophy/philosophy.html, GNU philosophy}
-should be adhered to.
-
-Note that we do now require a formal copyright assignment for GNUnet
-contributors to GNUnet e.V.; nevertheless, we do allow pseudonymous
-contributions. By signing the copyright agreement and submitting your
-code (or documentation) to us, you agree to share the rights to your
-code with GNUnet e.V.; GNUnet e.V. receives non-exclusive ownership
-rights, and in particular is allowed to dual-license the code. You
-retain non-exclusive rights to your contributions, so you can also
-share your contributions freely with other projects.
-
-GNUnet e.V. will publish all accepted contributions under the GPLv3
-or any later version. The association may decide to publish
-contributions under additional licenses (dual-licensing).
-
-We do not intentionally remove your name from your contributions;
-however, due to extensive editing it is not always trivial to
-attribute contributors properly. If you find that you significantly
-contributed to a file (or the project as a whole) and are not listed
-in the respective authors file or section, please do let us know.
-
-
-
-@menu
-
-* Philosophy:: About GNUnet
-* Vocabulary:: Vocabulary
-* GNUnet Installation Handbook:: How to install GNUnet
-* Using GNUnet:: Using GNUnet
-* GNUnet Developer Handbook:: Developing GNUnet
-* GNU Free Documentation License:: The license of this manual.
-* GNU General Public License:: The license of this manual.
-* Concept Index:: Concepts.
-* Programming Index:: Data types, functions, and variables.
-
-@detailmenu
- --- The Detailed Node Listing ---
-
-Philosophy
-
-* Design Goals::
-* Security & Privacy::
-* Versatility::
-* Practicality::
-* Key Concepts::
-* Authentication::
-* Accounting to Encourage Resource Sharing::
-* Confidentiality::
-* Anonymity::
-* Deniability::
-* Peer Identities::
-* Zones in the GNU Name System (GNS Zones)::
-* Egos::
-* Backup of Identities and Egos::
-* Revocation::
-
-Vocabulary
-
-* Words and characters::
-* Technical Assumptions::
-
-GNUnet Installation Handbook
-
-* Dependencies::
-* Pre-installation notes::
-* Generic installation instructions::
-* Build instructions for Ubuntu 12.04 using Git::
-* Build Instructions for Microsoft Windows Platforms::
-* Build instructions for Debian 7.5::
-* Installing GNUnet from Git on Ubuntu 14.4::
-* Build instructions for Debian 8::
-* Outdated build instructions for previous revisions::
-* Portable GNUnet::
-* The graphical configuration interface::
-* How to start and stop a GNUnet peer::
-
-Using GNUnet
-
-* Checking the Installation::
-* First steps - File-sharing::
-* First steps - Using the GNU Name System::
-* First steps - Using GNUnet Conversation::
-* First steps - Using the GNUnet VPN::
-* File-sharing::
-* The GNU Name System::
-* Using the Virtual Public Network::
-
-GNUnet Developer Handbook
-
-* Developer Introduction::
-* Code overview::
-* System Architecture::
-* Subsystem stability::
-* Naming conventions and coding style guide::
-* Build-system::
-* Developing extensions for GNUnet using the gnunet-ext template::
-* Writing testcases::
-* GNUnet's TESTING library::
-* Performance regression analysis with Gauger::
-* GNUnet's TESTBED Subsystem::
-* libgnunetutil::
-* The Automatic Restart Manager (ARM)::
-* GNUnet's TRANSPORT Subsystem::
-* NAT library::
-* Distance-Vector plugin::
-* SMTP plugin::
-* Bluetooth plugin::
-* WLAN plugin::
-* The ATS Subsystem::
-* GNUnet's CORE Subsystem::
-* GNUnet's CADET subsystem::
-* GNUnet's NSE subsystem::
-* GNUnet's HOSTLIST subsystem::
-* GNUnet's IDENTITY subsystem::
-* GNUnet's NAMESTORE Subsystem::
-* GNUnet's PEERINFO subsystem::
-* GNUnet's PEERSTORE subsystem::
-* GNUnet's SET Subsystem::
-* GNUnet's STATISTICS subsystem::
-* GNUnet's Distributed Hash Table (DHT)::
-* The GNU Name System (GNS)::
-* The GNS Namecache::
-* The REVOCATION Subsystem::
-* GNUnet's File-sharing (FS) Subsystem::
-* GNUnet's REGEX Subsystem::
-
-@end detailmenu
-@end menu
-
-@c *********************************************************************
-@include chapters/philosophy.texi
-@c *********************************************************************
-
-@include chapters/vocabulary.texi
-
-@c *********************************************************************
-@include chapters/installation.texi
-@c *********************************************************************
-
-@c *********************************************************************
-@include chapters/user.texi
-@c *********************************************************************
-
-@c *********************************************************************
-@include chapters/developer.texi
-@c @include gnunet-c-tutorial.texi
-@c *********************************************************************
-
-@c *********************************************************************
-@node GNU Free Documentation License
-@appendix GNU Free Documentation License
-@cindex license, GNU Free Documentation License
-@include fdl-1.3.texi
-
-@c *********************************************************************
-@node GNU General Public License
-@appendix GNU General Public License
-@cindex license, GNU General Public License
-@include gpl-3.0.texi
-
-@c *********************************************************************
-@node Concept Index
-@unnumbered Concept Index
-@printindex cp
-
-@node Programming Index
-@unnumbered Programming Index
-@syncodeindex tp fn
-@syncodeindex vr fn
-@printindex fn
-
-@bye
+++ /dev/null
-@c The GNU General Public License.
-@center Version 3, 29 June 2007
-
-@c This file is intended to be included within another document,
-@c hence no sectioning command or @node.
-
-@display
-Copyright @copyright{} 2007 Free Software Foundation, Inc. @url{http://fsf.org/}
-
-Everyone is permitted to copy and distribute verbatim copies of this
-license document, but changing it is not allowed.
-@end display
-
-@heading Preamble
-
-The GNU General Public License is a free, copyleft license for
-software and other kinds of works.
-
-The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works. By contrast,
-the GNU General Public License is intended to guarantee your freedom
-to share and change all versions of a program---to make sure it remains
-free software for all its users. We, the Free Software Foundation,
-use the GNU General Public License for most of our software; it
-applies also to any other work released this way by its authors. You
-can apply it to your programs, too.
-
-When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
-To protect your rights, we need to prevent others from denying you
-these rights or asking you to surrender the rights. Therefore, you
-have certain responsibilities if you distribute copies of the
-software, or if you modify it: responsibilities to respect the freedom
-of others.
-
-For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must pass on to the recipients the same
-freedoms that you received. You must make sure that they, too,
-receive or can get the source code. And you must show them these
-terms so they know their rights.
-
-Developers that use the GNU GPL protect your rights with two steps:
-(1) assert copyright on the software, and (2) offer you this License
-giving you legal permission to copy, distribute and/or modify it.
-
-For the developers' and authors' protection, the GPL clearly explains
-that there is no warranty for this free software. For both users' and
-authors' sake, the GPL requires that modified versions be marked as
-changed, so that their problems will not be attributed erroneously to
-authors of previous versions.
-
-Some devices are designed to deny users access to install or run
-modified versions of the software inside them, although the
-manufacturer can do so. This is fundamentally incompatible with the
-aim of protecting users' freedom to change the software. The
-systematic pattern of such abuse occurs in the area of products for
-individuals to use, which is precisely where it is most unacceptable.
-Therefore, we have designed this version of the GPL to prohibit the
-practice for those products. If such problems arise substantially in
-other domains, we stand ready to extend this provision to those
-domains in future versions of the GPL, as needed to protect the
-freedom of users.
-
-Finally, every program is threatened constantly by software patents.
-States should not allow patents to restrict development and use of
-software on general-purpose computers, but in those that do, we wish
-to avoid the special danger that patents applied to a free program
-could make it effectively proprietary. To prevent this, the GPL
-assures that patents cannot be used to render the program non-free.
-
-The precise terms and conditions for copying, distribution and
-modification follow.
-
-@heading TERMS AND CONDITIONS
-
-@enumerate 0
-@item Definitions.
-
-``This License'' refers to version 3 of the GNU General Public License.
-
-``Copyright'' also means copyright-like laws that apply to other kinds
-of works, such as semiconductor masks.
-
-``The Program'' refers to any copyrightable work licensed under this
-License. Each licensee is addressed as ``you''. ``Licensees'' and
-``recipients'' may be individuals or organizations.
-
-To ``modify'' a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of
-an exact copy. The resulting work is called a ``modified version'' of
-the earlier work or a work ``based on'' the earlier work.
-
-A ``covered work'' means either the unmodified Program or a work based
-on the Program.
-
-To ``propagate'' a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy. Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
-To ``convey'' a work means any kind of propagation that enables other
-parties to make or receive copies. Mere interaction with a user
-through a computer network, with no transfer of a copy, is not
-conveying.
-
-An interactive user interface displays ``Appropriate Legal Notices'' to
-the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License. If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
-@item Source Code.
-
-The ``source code'' for a work means the preferred form of the work for
-making modifications to it. ``Object code'' means any non-source form
-of a work.
-
-A ``Standard Interface'' means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
-The ``System Libraries'' of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form. A
-``Major Component'', in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
-The ``Corresponding Source'' for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities. However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work. For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
-The Corresponding Source need not include anything that users can
-regenerate automatically from other parts of the Corresponding Source.
-
-The Corresponding Source for a work in source code form is that same
-work.
-
-@item Basic Permissions.
-
-All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met. This License explicitly affirms your unlimited
-permission to run the unmodified Program. The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work. This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
-You may make, run and propagate covered works that you do not convey,
-without conditions so long as your license otherwise remains in force.
-You may convey covered works to others for the sole purpose of having
-them make modifications exclusively for you, or provide you with
-facilities for running those works, provided that you comply with the
-terms of this License in conveying all material for which you do not
-control copyright. Those thus making or running the covered works for
-you must do so exclusively on your behalf, under your direction and
-control, on terms that prohibit them from making any copies of your
-copyrighted material outside their relationship with you.
-
-Conveying under any other circumstances is permitted solely under the
-conditions stated below. Sublicensing is not allowed; section 10
-makes it unnecessary.
-
-@item Protecting Users' Legal Rights From Anti-Circumvention Law.
-
-No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
-When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such
-circumvention is effected by exercising rights under this License with
-respect to the covered work, and you disclaim any intention to limit
-operation or modification of the work as a means of enforcing, against
-the work's users, your or third parties' legal rights to forbid
-circumvention of technological measures.
-
-@item Conveying Verbatim Copies.
-
-You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
-You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
-@item Conveying Modified Source Versions.
-
-You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these
-conditions:
-
-@enumerate a
-@item
-The work must carry prominent notices stating that you modified it,
-and giving a relevant date.
-
-@item
-The work must carry prominent notices stating that it is released
-under this License and any conditions added under section 7. This
-requirement modifies the requirement in section 4 to ``keep intact all
-notices''.
-
-@item
-You must license the entire work, as a whole, under this License to
-anyone who comes into possession of a copy. This License will
-therefore apply, along with any applicable section 7 additional terms,
-to the whole of the work, and all its parts, regardless of how they
-are packaged. This License gives no permission to license the work in
-any other way, but it does not invalidate such permission if you have
-separately received it.
-
-@item
-If the work has interactive user interfaces, each must display
-Appropriate Legal Notices; however, if the Program has interactive
-interfaces that do not display Appropriate Legal Notices, your work
-need not make them do so.
-@end enumerate
-
-A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-``aggregate'' if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit. Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
-@item Conveying Non-Source Forms.
-
-You may convey a covered work in object code form under the terms of
-sections 4 and 5, provided that you also convey the machine-readable
-Corresponding Source under the terms of this License, in one of these
-ways:
-
-@enumerate a
-@item
-Convey the object code in, or embodied in, a physical product
-(including a physical distribution medium), accompanied by the
-Corresponding Source fixed on a durable physical medium customarily
-used for software interchange.
-
-@item
-Convey the object code in, or embodied in, a physical product
-(including a physical distribution medium), accompanied by a written
-offer, valid for at least three years and valid for as long as you
-offer spare parts or customer support for that product model, to give
-anyone who possesses the object code either (1) a copy of the
-Corresponding Source for all the software in the product that is
-covered by this License, on a durable physical medium customarily used
-for software interchange, for a price no more than your reasonable
-cost of physically performing this conveying of source, or (2) access
-to copy the Corresponding Source from a network server at no charge.
-
-@item
-Convey individual copies of the object code with a copy of the written
-offer to provide the Corresponding Source. This alternative is
-allowed only occasionally and noncommercially, and only if you
-received the object code with such an offer, in accord with subsection
-6b.
-
-@item
-Convey the object code by offering access from a designated place
-(gratis or for a charge), and offer equivalent access to the
-Corresponding Source in the same way through the same place at no
-further charge. You need not require recipients to copy the
-Corresponding Source along with the object code. If the place to copy
-the object code is a network server, the Corresponding Source may be
-on a different server (operated by you or a third party) that supports
-equivalent copying facilities, provided you maintain clear directions
-next to the object code saying where to find the Corresponding Source.
-Regardless of what server hosts the Corresponding Source, you remain
-obligated to ensure that it is available for as long as needed to
-satisfy these requirements.
-
-@item
-Convey the object code using peer-to-peer transmission, provided you
-inform other peers where the object code and Corresponding Source of
-the work are being offered to the general public at no charge under
-subsection 6d.
-
-@end enumerate
-
-A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
-A ``User Product'' is either (1) a ``consumer product'', which means any
-tangible personal property which is normally used for personal,
-family, or household purposes, or (2) anything designed or sold for
-incorporation into a dwelling. In determining whether a product is a
-consumer product, doubtful cases shall be resolved in favor of
-coverage. For a particular product received by a particular user,
-``normally used'' refers to a typical or common use of that class of
-product, regardless of the status of the particular user or of the way
-in which the particular user actually uses, or expects or is expected
-to use, the product. A product is a consumer product regardless of
-whether the product has substantial commercial, industrial or
-non-consumer uses, unless such uses represent the only significant
-mode of use of the product.
-
-``Installation Information'' for a User Product means any methods,
-procedures, authorization keys, or other information required to
-install and execute modified versions of a covered work in that User
-Product from a modified version of its Corresponding Source. The
-information must suffice to ensure that the continued functioning of
-the modified object code is in no case prevented or interfered with
-solely because modification has been made.
-
-If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information. But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
-The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or
-updates for a work that has been modified or installed by the
-recipient, or for the User Product in which it has been modified or
-installed. Access to a network may be denied when the modification
-itself materially and adversely affects the operation of the network
-or violates the rules and protocols for communication across the
-network.
-
-Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
-@item Additional Terms.
-
-``Additional permissions'' are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law. If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
-When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it. (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.) You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
-Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders
-of that material) supplement the terms of this License with terms:
-
-@enumerate a
-@item
-Disclaiming warranty or limiting liability differently from the terms
-of sections 15 and 16 of this License; or
-
-@item
-Requiring preservation of specified reasonable legal notices or author
-attributions in that material or in the Appropriate Legal Notices
-displayed by works containing it; or
-
-@item
-Prohibiting misrepresentation of the origin of that material, or
-requiring that modified versions of such material be marked in
-reasonable ways as different from the original version; or
-
-@item
-Limiting the use for publicity purposes of names of licensors or
-authors of the material; or
-
-@item
-Declining to grant rights under trademark law for use of some trade
-names, trademarks, or service marks; or
-
-@item
-Requiring indemnification of licensors and authors of that material by
-anyone who conveys the material (or modified versions of it) with
-contractual assumptions of liability to the recipient, for any
-liability that these contractual assumptions directly impose on those
-licensors and authors.
-@end enumerate
-
-All other non-permissive additional terms are considered ``further
-restrictions'' within the meaning of section 10. If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term. If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
-If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
-Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions; the
-above requirements apply either way.
-
-@item Termination.
-
-You may not propagate or modify a covered work except as expressly
-provided under this License. Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
-However, if you cease all violation of this License, then your license
-from a particular copyright holder is reinstated (a) provisionally,
-unless and until the copyright holder explicitly and finally
-terminates your license, and (b) permanently, if the copyright holder
-fails to notify you of the violation by some reasonable means prior to
-60 days after the cessation.
-
-Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
-Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License. If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
-@item Acceptance Not Required for Having Copies.
-
-You are not required to accept this License in order to receive or run
-a copy of the Program. Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance. However,
-nothing other than this License grants you permission to propagate or
-modify any covered work. These actions infringe copyright if you do
-not accept this License. Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
-@item Automatic Licensing of Downstream Recipients.
-
-Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License. You are not responsible
-for enforcing compliance by third parties with this License.
-
-An ``entity transaction'' is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations. If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
-You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License. For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
-@item Patents.
-
-A ``contributor'' is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based. The
-work thus licensed is called the contributor's ``contributor version''.
-
-A contributor's ``essential patent claims'' are all patent claims owned
-or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version. For
-purposes of this definition, ``control'' includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
-Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
-In the following three paragraphs, a ``patent license'' is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement). To ``grant'' such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
-If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients. ``Knowingly relying'' means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
-If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
-A patent license is ``discriminatory'' if it does not include within the
-scope of its coverage, prohibits the exercise of, or is conditioned on
-the non-exercise of one or more of the rights that are specifically
-granted under this License. You may not convey a covered work if you
-are a party to an arrangement with a third party that is in the
-business of distributing software, under which you make payment to the
-third party based on the extent of your activity of conveying the
-work, and under which the third party grants, to any of the parties
-who would receive the covered work from you, a discriminatory patent
-license (a) in connection with copies of the covered work conveyed by
-you (or copies made from those copies), or (b) primarily for and in
-connection with specific products or compilations that contain the
-covered work, unless you entered into that arrangement, or that patent
-license was granted, prior to 28 March 2007.
-
-Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
-@item No Surrender of Others' Freedom.
-
-If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot convey
-a covered work so as to satisfy simultaneously your obligations under
-this License and any other pertinent obligations, then as a
-consequence you may not convey it at all. For example, if you agree
-to terms that obligate you to collect a royalty for further conveying
-from those to whom you convey the Program, the only way you could
-satisfy both those terms and this License would be to refrain entirely
-from conveying the Program.
-
-@item Use with the GNU Affero General Public License.
-
-Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU Affero General Public License into a single
-combined work, and to convey the resulting work. The terms of this
-License will continue to apply to the part which is the covered work,
-but the special requirements of the GNU Affero General Public License,
-section 13, concerning interaction through a network will apply to the
-combination as such.
-
-@item Revised Versions of this License.
-
-The Free Software Foundation may publish revised and/or new versions
-of the GNU General Public License from time to time. Such new
-versions will be similar in spirit to the present version, but may
-differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies that a certain numbered version of the GNU General Public
-License ``or any later version'' applies to it, you have the option of
-following the terms and conditions either of that numbered version or
-of any later version published by the Free Software Foundation. If
-the Program does not specify a version number of the GNU General
-Public License, you may choose any version ever published by the Free
-Software Foundation.
-
-If the Program specifies that a proxy can decide which future versions
-of the GNU General Public License can be used, that proxy's public
-statement of acceptance of a version permanently authorizes you to
-choose that version for the Program.
-
-Later license versions may give you additional or different
-permissions. However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
-@item Disclaimer of Warranty.
-
-THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW@. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM ``AS IS'' WITHOUT
-WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE@. THE ENTIRE RISK AS TO THE QUALITY AND
-PERFORMANCE OF THE PROGRAM IS WITH YOU@. SHOULD THE PROGRAM PROVE
-DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
-CORRECTION.
-
-@item Limitation of Liability.
-
-IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR
-CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES
-ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT
-NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR
-LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM
-TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER
-PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
-
-@item Interpretation of Sections 15 and 16.
-
-If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
-@end enumerate
-
-@heading END OF TERMS AND CONDITIONS
-
-@heading How to Apply These Terms to Your New Programs
-
-If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these
-terms.
-
-To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the ``copyright'' line and a pointer to where the full notice is found.
-
-@smallexample
-@var{one line to give the program's name and a brief idea of what it does.}
-Copyright (C) @var{year} @var{name of author}
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or (at
-your option) any later version.
-
-This program is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE@. See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see @url{http://www.gnu.org/licenses/}.
-@end smallexample
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program does terminal interaction, make it output a short
-notice like this when it starts in an interactive mode:
-
-@smallexample
-@var{program} Copyright (C) @var{year} @var{name of author}
-This program comes with ABSOLUTELY NO WARRANTY; for details type @samp{show w}.
-This is free software, and you are welcome to redistribute it
-under certain conditions; type @samp{show c} for details.
-@end smallexample
-
-The hypothetical commands @samp{show w} and @samp{show c} should show
-the appropriate parts of the General Public License. Of course, your
-program's commands might be different; for a GUI interface, you would
-use an ``about box''.
-
-You should also get your employer (if you work as a programmer) or school,
-if any, to sign a ``copyright disclaimer'' for the program, if necessary.
-For more information on this, and how to apply and follow the GNU GPL, see
-@url{http://www.gnu.org/licenses/}.
-
-The GNU General Public License does not permit incorporating your
-program into proprietary programs. If your program is a subroutine
-library, you may consider it more useful to permit linking proprietary
-applications with the library. If this is what you want to do, use
-the GNU Lesser General Public License instead of this License. But
-first, please read @url{http://www.gnu.org/philosophy/why-not-lgpl.html}.
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="744.09448819"
- height="1052.3622047"
- id="svg6781"
- version="1.1"
- inkscape:version="0.48.2 r9819"
- sodipodi:docname="New document 58">
- <defs
- id="defs6783" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="0.35"
- inkscape:cx="375"
- inkscape:cy="520"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="false"
- inkscape:window-width="1366"
- inkscape:window-height="721"
- inkscape:window-x="-2"
- inkscape:window-y="-3"
- inkscape:window-maximized="1" />
- <metadata
- id="metadata6786">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1">
- <g
- transform="translate(-4.5298577,-148.04661)"
- id="g6746">
- <path
- style="fill:#5fd38d;fill-opacity:1;stroke:#faf6a2;stroke-width:1.99014676;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
- d="m 183.84284,595.7683 350.8064,0 0,202.04036 -350.8064,0 z"
- id="path6693"
- inkscape:connector-curvature="0" />
- <rect
- style="fill:#ffffff;fill-opacity:1;stroke:#faf6a2;stroke-width:2.22747946;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0"
- id="rect6695"
- width="66.670067"
- height="75.18058"
- x="223.74881"
- y="737.19458" />
- <rect
- y="737.19458"
- x="331.83514"
- height="67.323441"
- width="66.670067"
- id="rect6697"
- style="fill:#ffffff;fill-opacity:1;stroke:#faf6a2;stroke-width:2.10787106;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" />
- <rect
- style="fill:#ffffff;fill-opacity:1;stroke:#faf6a2;stroke-width:2.06117821;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0"
- id="rect6699"
- width="66.670067"
- height="64.373825"
- x="434.8707"
- y="737.19458" />
- <path
- style="fill:#37c871;fill-opacity:1;stroke:#faf6a2;stroke-width:0.98368376;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
- d="m 223.60976,736.21851 67.23534,0.38374 0,23.63648 -67.23534,37.13818 z"
- id="path6701"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccccc" />
- <path
- sodipodi:nodetypes="ccccc"
- inkscape:connector-curvature="0"
- id="path6703"
- d="m 331.69608,736.21851 67.23534,0.3894 0,23.98466 -67.23534,37.68524 z"
- style="fill:#37c871;fill-opacity:1;stroke:#faf6a2;stroke-width:0.99090236;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" />
- <path
- style="fill:#37c871;fill-opacity:1;stroke:#faf6a2;stroke-width:0.98368376;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
- d="m 434.73164,736.21851 67.23534,0.38374 0,23.63648 -67.23534,37.13818 z"
- id="path6705"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccccc" />
- <path
- style="fill:#37c871;fill-opacity:1;stroke:#faf6a2;stroke-width:1.92068994;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
- d="m 533.72659,595.02309 56.12366,-29.34622 -1.01015,190.24271 -55.11351,41.45733 z"
- id="path6707"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccccc" />
- <path
- style="fill:#37c871;fill-opacity:1;stroke:#faf6a2;stroke-width:1.99424875;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
- d="m 245.46708,566.47881 345.46203,-1.01015 -56.56854,31.31472 -349.50264,-1.01014 z"
- id="path6709"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccccc" />
- <text
- sodipodi:linespacing="125%"
- id="text6715"
- y="677.59558"
- x="234.35539"
- style="font-size:36px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
- xml:space="preserve"><tspan
- y="677.59558"
- x="234.35539"
- id="tspan6717"
- sodipodi:role="line">User Interface</tspan></text>
- </g>
- </g>
-</svg>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="744.09448819"
- height="1052.3622047"
- id="svg2"
- version="1.1"
- inkscape:version="0.48.1 r9760"
- sodipodi:docname="System.svg">
- <defs
- id="defs4">
- <linearGradient
- id="linearGradient6602">
- <stop
- style="stop-color:#df8060;stop-opacity:1;"
- offset="0"
- id="stop6604" />
- <stop
- style="stop-color:#df8002;stop-opacity:0;"
- offset="1"
- id="stop6606" />
- </linearGradient>
- <linearGradient
- id="linearGradient4392"
- osb:paint="solid">
- <stop
- style="stop-color:#faf6a6;stop-opacity:1;"
- offset="0"
- id="stop4394" />
- </linearGradient>
- <inkscape:perspective
- sodipodi:type="inkscape:persp3d"
- inkscape:vp_x="883.99395 : 559.99673 : 1"
- inkscape:vp_y="13.319386 : 993.87659 : 0"
- inkscape:vp_z="285.3157 : 504.79962 : 1"
- inkscape:persp3d-origin="481.39556 : 281.96355 : 1"
- id="perspective3070" />
- <inkscape:perspective
- sodipodi:type="inkscape:persp3d"
- inkscape:vp_x="76.097926 : 349.87282 : 1"
- inkscape:vp_y="-13.319386 : 979.366 : 0"
- inkscape:vp_z="752.55793 : 376.31441 : 1"
- inkscape:persp3d-origin="373.64045 : 350.98006 : 1"
- id="perspective3012" />
- </defs>
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="0.98994949"
- inkscape:cx="322.06882"
- inkscape:cy="568.82291"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="false"
- inkscape:window-width="846"
- inkscape:window-height="963"
- inkscape:window-x="59"
- inkscape:window-y="0"
- inkscape:window-maximized="0" />
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1">
- <text
- xml:space="preserve"
- style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
- x="352.03815"
- y="-190.12544"
- id="text6623"
- sodipodi:linespacing="125%"><tspan
- sodipodi:role="line"
- id="tspan6625"
- x="352.03815"
- y="-190.12544" /></text>
- <text
- xml:space="preserve"
- style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
- x="338.40109"
- y="-300.73715"
- id="text6627"
- sodipodi:linespacing="125%"><tspan
- sodipodi:role="line"
- id="tspan6629"
- x="338.40109"
- y="-300.73715" /></text>
- <g
- style="font-size:24px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
- id="text6643" />
- <text
- xml:space="preserve"
- style="font-size:24px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
- x="71.720833"
- y="95.747719"
- id="text6648"
- sodipodi:linespacing="125%"><tspan
- sodipodi:role="line"
- id="tspan6650"
- x="71.720833"
- y="95.747719" /></text>
- <text
- xml:space="preserve"
- style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
- x="262.63965"
- y="666.48389"
- id="text6711"
- sodipodi:linespacing="125%"><tspan
- sodipodi:role="line"
- id="tspan6713"
- x="262.63965"
- y="666.48389" /></text>
- <path
- inkscape:connector-curvature="0"
- id="path3506"
- d="m 198.00647,673.76257 236.93358,0 0,158.2919 -236.93358,0 z"
- style="fill:#000000;fill-opacity:1;stroke:#faf6a2;stroke-width:1.44768786;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" />
- <path
- sodipodi:nodetypes="ccccc"
- inkscape:connector-curvature="0"
- id="path3432"
- d="m 169.32669,654.90334 464.83332,-2.26992 -33.76593,25.73079 -483.97287,-0.12904 z"
- style="fill:#deaa87;fill-opacity:1;stroke:#faf6a2;stroke-width:2.18398547;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" />
- <rect
- style="fill:#000000;fill-opacity:1;stroke:#59000c;stroke-width:1.35822594;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0.48230088;stroke-dasharray:none;stroke-dashoffset:0"
- id="rect3416"
- width="28.495705"
- height="172.2845"
- x="464.19418"
- y="518.96954" />
- <rect
- style="fill:#000000;fill-opacity:1;stroke:#59000c;stroke-width:1.36876941;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0.48230088;stroke-dasharray:none;stroke-dashoffset:0"
- id="rect3414"
- width="34.729141"
- height="170.67587"
- x="340.86124"
- y="517.93475" />
- <path
- style="fill:#deaa87;fill-opacity:1;stroke:#faf6a2;stroke-width:2.04969239;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
- d="m 246.8138,499.06358 386.50295,-0.94821 -41.88736,26.04231 -413.96081,0 z"
- id="rect6568-0"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccccc" />
- <path
- style="fill:#ffdd55;fill-opacity:1;stroke:#faf6a2;stroke-width:1.49989259;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
- d="m 276.05867,399.52042 323.05541,0 0,124.61741 -323.05541,0 z"
- id="rect5973"
- inkscape:connector-curvature="0" />
- <path
- style="fill:#ffcc00;fill-opacity:1;stroke:#faf6a2;stroke-width:1.19094384;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
- d="m 599.16863,399.06078 34.35465,-18.10059 0,117.34068 -34.35465,25.57066 z"
- id="rect6542"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccccc" />
- <rect
- style="fill:#c87137;fill-opacity:1;stroke:#c48069;stroke-width:1.50087094;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0"
- id="rect6557"
- width="322.88623"
- height="30.529778"
- x="276.67755"
- y="368.99368" />
- <path
- style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:0.50882494;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
- d="m 598.94047,368.99367 34.58281,-16.82253 0,28.66061 -34.58281,18.06864 z"
- id="rect6561"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccccc" />
- <path
- sodipodi:nodetypes="ccccc"
- inkscape:connector-curvature="0"
- id="path6564"
- d="m 598.94047,369.07046 34.30741,-17.12981 0,29.18412 -34.30741,18.39868 z"
- style="fill:#c87137;fill-opacity:1;stroke:#faf6a2;stroke-width:0.51140249;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
- inkscape:transform-center-x="-70.147578"
- inkscape:transform-center-y="15.429055" />
- <path
- style="fill:#d38d5f;fill-opacity:1;stroke:#faf6a2;stroke-width:1.47079194;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
- d="m 330.2508,353.23478 302.87005,-0.62306 -38.33414,16.82253 -318.87597,0 z"
- id="rect6568"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccccc" />
- <text
- xml:space="preserve"
- style="font-size:22.32217598px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
- x="391.63083"
- y="461.858"
- id="text6656"
- sodipodi:linespacing="125%"
- transform="scale(1.0052948,0.9947331)"><tspan
- sodipodi:role="line"
- id="tspan6658"
- x="391.63083"
- y="461.858">Service</tspan></text>
- <path
- sodipodi:nodetypes="ccccc"
- inkscape:connector-curvature="0"
- id="path6707"
- d="m 598.75503,244.83802 34.98432,-18.10059 0.26082,125.2709 -35.24514,17.64044 z"
- style="fill:#37c871;fill-opacity:1;stroke:#faf6a2;stroke-width:1.19094384;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" />
- <path
- sodipodi:nodetypes="ccccc"
- inkscape:connector-curvature="0"
- id="path6709"
- d="m 419.07032,228.1132 214.71185,-1.24611 -34.63196,19.9378 L 381.29,246.18184 z"
- style="fill:#37c871;fill-opacity:1;stroke:#faf6a2;stroke-width:1.23655474;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" />
- <rect
- style="fill:#5fd38d;fill-opacity:1;stroke:#c48069;stroke-width:1.23640049;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0"
- id="rect7224"
- width="217.86653"
- height="122.74216"
- x="381.70358"
- y="246.25151" />
- <text
- xml:space="preserve"
- style="font-size:22.32217598px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
- x="409.16376"
- y="302.05649"
- id="text6715"
- sodipodi:linespacing="125%"
- transform="scale(1.0052948,0.9947331)"><tspan
- sodipodi:role="line"
- id="tspan6717"
- x="409.16376"
- y="302.05649">User Interface</tspan></text>
- <g
- id="g7219"
- transform="matrix(0.62334353,0,0,0.61679464,281.18563,257.70936)">
- <rect
- y="119.99139"
- x="198.49498"
- height="60.609154"
- width="66.670067"
- id="rect6571"
- style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" />
- <text
- sodipodi:linespacing="125%"
- id="text6631"
- y="160.39748"
- x="206.07112"
- style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
- xml:space="preserve"><tspan
- y="160.39748"
- x="206.07112"
- id="tspan6633"
- sodipodi:role="line">API</tspan></text>
- </g>
- <g
- transform="matrix(0.62334353,0,0,0.61679464,344.78251,257.70936)"
- id="g7226">
- <rect
- style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0"
- id="rect7228"
- width="66.670067"
- height="60.609154"
- x="198.49498"
- y="119.99139" />
- <text
- xml:space="preserve"
- style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
- x="206.07112"
- y="160.39748"
- id="text7230"
- sodipodi:linespacing="125%"><tspan
- sodipodi:role="line"
- id="tspan7232"
- x="206.07112"
- y="160.39748">API</tspan></text>
- </g>
- <g
- id="g7234"
- transform="matrix(0.62334353,0,0,0.61679464,409.3239,257.70936)">
- <rect
- y="119.99139"
- x="198.49498"
- height="60.609154"
- width="66.670067"
- id="rect7236"
- style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" />
- <text
- sodipodi:linespacing="125%"
- id="text7238"
- y="160.39748"
- x="206.07112"
- style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
- xml:space="preserve"><tspan
- y="160.39748"
- x="206.07112"
- id="tspan7240"
- sodipodi:role="line">API</tspan></text>
- </g>
- <g
- transform="matrix(0.62334353,0,0,0.61679464,175.75806,412.85048)"
- id="g7242">
- <rect
- style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0"
- id="rect7244"
- width="66.670067"
- height="60.609154"
- x="198.49498"
- y="119.99139" />
- <text
- xml:space="preserve"
- style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
- x="206.07112"
- y="160.39748"
- id="text7246"
- sodipodi:linespacing="125%"><tspan
- sodipodi:role="line"
- id="tspan7248"
- x="206.07112"
- y="160.39748">API</tspan></text>
- </g>
- <g
- id="g7250"
- transform="matrix(0.62334353,0,0,0.61679464,240.79871,413.29105)">
- <rect
- y="119.99139"
- x="198.49498"
- height="60.609154"
- width="66.670067"
- id="rect7252"
- style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" />
- <text
- sodipodi:linespacing="125%"
- id="text7254"
- y="160.39748"
- x="206.07112"
- style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
- xml:space="preserve"><tspan
- y="160.39748"
- x="206.07112"
- id="tspan7256"
- sodipodi:role="line">API</tspan></text>
- </g>
- <g
- transform="matrix(0.62334353,0,0,0.61679464,303.79756,412.40991)"
- id="g7258">
- <rect
- style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0"
- id="rect7260"
- width="66.670067"
- height="60.609154"
- x="198.49498"
- y="119.99139" />
- <text
- xml:space="preserve"
- style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
- x="206.07112"
- y="160.39748"
- id="text7262"
- sodipodi:linespacing="125%"><tspan
- sodipodi:role="line"
- id="tspan7264"
- x="206.07112"
- y="160.39748">API</tspan></text>
- </g>
- <g
- id="g7266"
- transform="matrix(0.62334353,0,0,0.61679464,369.88148,412.40991)">
- <rect
- y="119.99139"
- x="198.49498"
- height="60.609154"
- width="66.670067"
- id="rect7268"
- style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" />
- <text
- sodipodi:linespacing="125%"
- id="text7270"
- y="160.39748"
- x="206.07112"
- style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
- xml:space="preserve"><tspan
- y="160.39748"
- x="206.07112"
- id="tspan7272"
- sodipodi:role="line">API</tspan></text>
- </g>
- <path
- style="fill:#ffeeaa;fill-opacity:1;stroke:#faf6a2;stroke-width:0.91879815;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
- d="m 478.56081,554.09281 121.22633,0 0,124.61741 -121.22633,0 z"
- id="rect5973-1"
- inkscape:connector-curvature="0" />
- <g
- transform="matrix(0.62334353,0,0,0.61679464,422.424,566.60858)"
- id="g3474">
- <rect
- style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0"
- id="rect3476"
- width="66.670067"
- height="60.609154"
- x="198.49498"
- y="119.99139" />
- <text
- xml:space="preserve"
- style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
- x="206.07112"
- y="160.39748"
- id="text3478"
- sodipodi:linespacing="125%"><tspan
- sodipodi:role="line"
- id="tspan3480"
- x="206.07112"
- y="160.39748">API</tspan></text>
- </g>
- <path
- style="fill:#ffe680;fill-opacity:1;stroke:#faf6a2;stroke-width:1.18771458;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
- d="m 599.60339,554.02055 33.72575,-29.55535 0.88568,128.35487 -34.61143,26.01123 z"
- id="rect6542-8"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccccc" />
- <path
- sodipodi:nodetypes="ccccc"
- inkscape:connector-curvature="0"
- id="path6564-2"
- d="m 598.92998,524.03024 34.30741,-25.94116 0,26.5407 -34.30741,29.85344 z"
- style="fill:#d38d5f;fill-opacity:1;stroke:#faf6a2;stroke-width:0.51140249;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
- inkscape:transform-center-x="-70.147578"
- inkscape:transform-center-y="15.429055" />
- <path
- inkscape:transform-center-y="15.492457"
- inkscape:transform-center-x="-70.147578"
- style="fill:#c87137;fill-opacity:1;stroke:#faf6a2;stroke-width:0.51245213;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
- d="m 598.92998,524.13683 34.30741,-26.04775 0,26.64977 -34.30741,29.97611 z"
- id="path3402"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccccc" />
- <path
- sodipodi:nodetypes="ccccc"
- inkscape:connector-curvature="0"
- id="path3404"
- d="m 599.82047,678.2289 34.30741,-25.94116 0,26.5407 -34.30741,34.25912 z"
- style="fill:#c87137;fill-opacity:1;stroke:#faf6a2;stroke-width:0.51140249;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
- inkscape:transform-center-x="-70.147578"
- inkscape:transform-center-y="15.429055" />
- <path
- sodipodi:nodetypes="ccccc"
- inkscape:connector-curvature="0"
- id="path3406"
- d="m 600.04863,707.77865 33.90941,-29.55535 0.89049,128.35487 -34.7999,26.01123 z"
- style="fill:#37c837;fill-opacity:1;stroke:#faf6a2;stroke-width:1.19094384;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" />
- <path
- inkscape:connector-curvature="0"
- id="path3410"
- d="m 356.56358,554.09281 120.92249,0 0,124.19268 -120.92249,0 z"
- style="fill:#ffeeaa;fill-opacity:1;stroke:#faf6a2;stroke-width:0.91608089;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" />
- <path
- style="fill:#ffeeaa;fill-opacity:1;stroke:#faf6a2;stroke-width:1.11023378;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
- d="m 177.52518,554.09281 177.51841,0 0,124.25702 -177.51841,0 z"
- id="path3412"
- inkscape:connector-curvature="0" />
- <rect
- style="fill:#c87137;fill-opacity:1;stroke:#c48069;stroke-width:1.11264122;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0"
- id="rect6557-7"
- width="177.44882"
- height="30.529778"
- x="177.65657"
- y="523.95343" />
- <rect
- y="678.1521"
- x="116.73995"
- height="29.53463"
- width="177.54182"
- id="rect3408"
- style="fill:#c87137;fill-opacity:1;stroke:#c48069;stroke-width:1.09464383;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" />
- <rect
- y="523.95343"
- x="356.55023"
- height="30.529778"
- width="120.86897"
- id="rect3420"
- style="fill:#c87137;fill-opacity:1;stroke:#c48069;stroke-width:0.91828173;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" />
- <rect
- style="fill:#c87137;fill-opacity:1;stroke:#c48069;stroke-width:0.91828173;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0"
- id="rect3422"
- width="120.86897"
- height="30.529778"
- x="478.54919"
- y="523.95343" />
- <text
- xml:space="preserve"
- style="font-size:22.32217598px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
- x="372.34232"
- y="622.53217"
- id="text6656-2"
- sodipodi:linespacing="125%"
- transform="scale(1.0052948,0.9947331)"><tspan
- sodipodi:role="line"
- id="tspan6658-2"
- x="372.34232"
- y="622.53217">Service</tspan></text>
- <text
- sodipodi:linespacing="125%"
- id="text3424"
- y="622.53217"
- x="220.56013"
- style="font-size:22.32217598px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
- xml:space="preserve"
- transform="scale(1.0052948,0.9947331)"><tspan
- y="622.53217"
- x="220.56013"
- id="tspan3426"
- sodipodi:role="line">Service</tspan></text>
- <text
- xml:space="preserve"
- style="font-size:22.32217598px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
- x="493.85532"
- y="622.54492"
- id="text3428"
- sodipodi:linespacing="125%"
- transform="scale(1.0052948,0.9947331)"><tspan
- sodipodi:role="line"
- id="tspan3430"
- x="493.85532"
- y="622.54492">Service</tspan></text>
- <g
- id="g3434"
- transform="matrix(0.62334353,0,0,0.61679464,120.10238,566.60858)">
- <rect
- y="119.99139"
- x="198.49498"
- height="60.609154"
- width="66.670067"
- id="rect3436"
- style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" />
- <text
- sodipodi:linespacing="125%"
- id="text3438"
- y="160.39748"
- x="206.07112"
- style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
- xml:space="preserve"><tspan
- y="160.39748"
- x="206.07112"
- id="tspan3440"
- sodipodi:role="line">API</tspan></text>
- </g>
- <g
- transform="matrix(0.62334353,0,0,0.61679464,181.54625,566.60858)"
- id="g3442">
- <rect
- style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0"
- id="rect3444"
- width="66.670067"
- height="60.609154"
- x="198.49498"
- y="119.99139" />
- <text
- xml:space="preserve"
- style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
- x="206.07112"
- y="160.39748"
- id="text3446"
- sodipodi:linespacing="125%"><tspan
- sodipodi:role="line"
- id="tspan3448"
- x="206.07112"
- y="160.39748">API</tspan></text>
- </g>
- <g
- id="g3450"
- transform="matrix(0.62334353,0,0,0.61679464,242.09962,566.60858)">
- <rect
- y="119.99139"
- x="198.49498"
- height="60.609154"
- width="66.670067"
- id="rect3452"
- style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" />
- <text
- sodipodi:linespacing="125%"
- id="text3454"
- y="160.39748"
- x="206.07112"
- style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
- xml:space="preserve"><tspan
- y="160.39748"
- x="206.07112"
- id="tspan3456"
- sodipodi:role="line">API</tspan></text>
- </g>
- <g
- transform="matrix(0.62334353,0,0,0.61679464,303.54348,566.60858)"
- id="g3458">
- <rect
- style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0"
- id="rect3460"
- width="66.670067"
- height="60.609154"
- x="198.49498"
- y="119.99139" />
- <text
- xml:space="preserve"
- style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
- x="206.07112"
- y="160.39748"
- id="text3462"
- sodipodi:linespacing="125%"><tspan
- sodipodi:role="line"
- id="tspan3464"
- x="206.07112"
- y="160.39748">API</tspan></text>
- </g>
- <g
- id="g3466"
- transform="matrix(0.62334353,0,0,0.61679464,362.76112,566.60858)">
- <rect
- y="119.99139"
- x="198.49498"
- height="60.609154"
- width="66.670067"
- id="rect3468"
- style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" />
- <text
- sodipodi:linespacing="125%"
- id="text3470"
- y="160.39748"
- x="206.07112"
- style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
- xml:space="preserve"><tspan
- y="160.39748"
- x="206.07112"
- id="tspan3472"
- sodipodi:role="line">API</tspan></text>
- </g>
- <path
- style="fill:#5fd35f;fill-opacity:1;stroke:#faf6a2;stroke-width:1.11993289;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
- d="m 420.2626,707.53388 180.11119,0 0,124.61741 -180.11119,0 z"
- id="path3490"
- inkscape:connector-curvature="0" />
- <g
- transform="matrix(0.62334353,0,0,0.61679464,62.665728,566.60858)"
- id="g3492">
- <rect
- style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0"
- id="rect3494"
- width="66.670067"
- height="60.609154"
- x="198.49498"
- y="119.99139" />
- <text
- xml:space="preserve"
- style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
- x="206.07112"
- y="160.39748"
- id="text3496"
- sodipodi:linespacing="125%"><tspan
- sodipodi:role="line"
- id="tspan3498"
- x="206.07112"
- y="160.39748">API</tspan></text>
- </g>
- <path
- inkscape:connector-curvature="0"
- id="path3500"
- d="m 116.52597,707.54132 177.63643,0 0,124.61741 -177.63643,0 z"
- style="fill:#5fd35f;fill-opacity:1;stroke:#faf6a2;stroke-width:1.11221218;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" />
- <path
- style="fill:#5fd35f;fill-opacity:1;stroke:#faf6a2;stroke-width:0.92545629;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
- d="m 295.65636,707.63061 122.98965,0 0,124.61741 -122.98965,0 z"
- id="path3502"
- inkscape:connector-curvature="0" />
- <text
- xml:space="preserve"
- style="font-size:22.32217598px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
- x="162.54019"
- y="779.76184"
- id="text3508"
- sodipodi:linespacing="125%"
- transform="scale(1.0052948,0.9947331)"><tspan
- sodipodi:role="line"
- id="tspan3510"
- x="162.54019"
- y="779.76184">Service</tspan></text>
- <text
- sodipodi:linespacing="125%"
- id="text3512"
- y="779.7619"
- x="313.56918"
- style="font-size:22.32217598px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
- xml:space="preserve"
- transform="scale(1.0052948,0.9947331)"><tspan
- y="779.7619"
- x="313.56918"
- id="tspan3514"
- sodipodi:role="line">Service</tspan></text>
- <text
- xml:space="preserve"
- style="font-size:22.32217598px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
- x="465.48401"
- y="779.7619"
- id="text3516"
- sodipodi:linespacing="125%"
- transform="scale(1.0052948,0.9947331)"><tspan
- sodipodi:role="line"
- id="tspan3518"
- x="465.48401"
- y="779.7619">Service</tspan></text>
- <rect
- style="fill:#c87137;fill-opacity:1;stroke:#c48069;stroke-width:0.91063529;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0"
- id="rect3520"
- width="122.86946"
- height="29.53463"
- x="295.75125"
- y="678.1521" />
- <rect
- y="678.1521"
- x="420.27423"
- height="29.53463"
- width="179.80205"
- id="rect3522"
- style="fill:#c87137;fill-opacity:1;stroke:#c48069;stroke-width:1.10158956;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" />
- </g>
-</svg>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="744.09448819"
- height="1052.3622047"
- id="svg2"
- version="1.1"
- inkscape:version="0.48.2 r9819"
- sodipodi:docname="Lego block 3.svg">
- <defs
- id="defs4">
- <linearGradient
- id="linearGradient6602">
- <stop
- style="stop-color:#df8060;stop-opacity:1;"
- offset="0"
- id="stop6604" />
- <stop
- style="stop-color:#df8002;stop-opacity:0;"
- offset="1"
- id="stop6606" />
- </linearGradient>
- <linearGradient
- id="linearGradient4392"
- osb:paint="solid">
- <stop
- style="stop-color:#faf6a6;stop-opacity:1;"
- offset="0"
- id="stop4394" />
- </linearGradient>
- <inkscape:perspective
- sodipodi:type="inkscape:persp3d"
- inkscape:vp_x="883.99395 : 559.99673 : 1"
- inkscape:vp_y="13.319386 : 993.87659 : 0"
- inkscape:vp_z="285.3157 : 504.79962 : 1"
- inkscape:persp3d-origin="481.39556 : 281.96355 : 1"
- id="perspective3070" />
- <inkscape:perspective
- sodipodi:type="inkscape:persp3d"
- inkscape:vp_x="76.097926 : 349.87282 : 1"
- inkscape:vp_y="-13.319386 : 979.366 : 0"
- inkscape:vp_z="752.55793 : 376.31441 : 1"
- inkscape:persp3d-origin="373.64045 : 350.98006 : 1"
- id="perspective3012" />
- </defs>
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="0.49497475"
- inkscape:cx="385.59974"
- inkscape:cy="826.03166"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="false"
- inkscape:window-width="1366"
- inkscape:window-height="721"
- inkscape:window-x="-2"
- inkscape:window-y="-3"
- inkscape:window-maximized="1" />
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1">
- <path
- style="fill:#ffdd55;fill-opacity:1;stroke:#faf6a2;stroke-width:2.26315212;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
- d="m 74.934278,230.09308 453.654042,0 0,202.04036 -453.654042,0 z"
- id="rect5973"
- inkscape:connector-curvature="0" />
- <path
- style="fill:#ffcc00;fill-opacity:1;stroke:#faf6a2;stroke-width:1.92068994;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
- d="m 528.67583,229.34787 55.11351,-29.34622 0,190.24271 -55.11351,41.45733 z"
- id="rect6542"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccccc" />
- <rect
- style="fill:#d38d5f;fill-opacity:1;stroke:#c48069;stroke-width:2.2674458;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0"
- id="rect6557"
- width="454.54535"
- height="49.497475"
- x="74.764442"
- y="180.60052" />
- <path
- style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:0.8206054;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
- d="m 528.30981,180.60052 55.47954,-27.27412 0,46.46702 -55.47954,29.29442 z"
- id="rect6561"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccccc" />
- <path
- sodipodi:nodetypes="ccccc"
- inkscape:connector-curvature="0"
- id="path6564"
- d="m 528.30981,180.72501 55.03773,-27.7723 0,47.31578 -55.03773,29.8295 z"
- style="fill:#d38d5f;fill-opacity:1;stroke:#faf6a2;stroke-width:0.82476228;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
- inkscape:transform-center-x="-70.147578"
- inkscape:transform-center-y="15.429055" />
- <path
- style="fill:#deaa87;fill-opacity:1;stroke:#faf6a2;stroke-width:2.23265362;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
- d="m 153.39374,154.33657 430.4643,-1.01015 -54.4837,27.27411 -453.213248,0 z"
- id="rect6568"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccccc" />
- <text
- xml:space="preserve"
- style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
- x="352.03815"
- y="-190.12544"
- id="text6623"
- sodipodi:linespacing="125%"><tspan
- sodipodi:role="line"
- id="tspan6625"
- x="352.03815"
- y="-190.12544" /></text>
- <text
- xml:space="preserve"
- style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
- x="338.40109"
- y="-300.73715"
- id="text6627"
- sodipodi:linespacing="125%"><tspan
- sodipodi:role="line"
- id="tspan6629"
- x="338.40109"
- y="-300.73715" /></text>
- <rect
- style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0"
- id="rect6571"
- width="66.670067"
- height="60.609154"
- x="198.49498"
- y="119.99139" />
- <path
- style="fill:#ff6600;fill-opacity:1;stroke:#faf6a2;stroke-width:1.98413372;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
- d="m 265.16503,119.45792 44.95179,-22.465406 0,57.057986 -44.95179,26.55003 z"
- id="path6600"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccccc" />
- <path
- style="fill:#ff6600;fill-opacity:1;stroke:#c48069;stroke-width:1.99687159;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
- d="m 243.06977,97.26295 66.86223,10e-7 -45.08135,22.728439 -66.3557,0 z"
- id="path6617"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccccc" />
- <text
- xml:space="preserve"
- style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
- x="206.07112"
- y="160.39748"
- id="text6631"
- sodipodi:linespacing="125%"><tspan
- sodipodi:role="line"
- id="tspan6633"
- x="206.07112"
- y="160.39748">API</tspan></text>
- <rect
- y="119.99139"
- x="313.65237"
- height="60.609154"
- width="66.670067"
- id="rect6573"
- style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" />
- <path
- sodipodi:nodetypes="ccccc"
- inkscape:connector-curvature="0"
- id="path6598"
- d="m 379.81735,119.56755 44.95179,-22.425126 0,56.955676 -44.95179,26.50243 z"
- style="fill:#ff6600;fill-opacity:1;stroke:#faf6a2;stroke-width:1.98235416;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" />
- <path
- sodipodi:nodetypes="ccccc"
- inkscape:connector-curvature="0"
- id="path6615"
- d="m 358.25117,97.26295 66.89824,10e-7 -45.10563,22.728439 -66.39143,0 z"
- style="fill:#ff6600;fill-opacity:1;stroke:#c48069;stroke-width:1.99740911;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" />
- <text
- sodipodi:linespacing="125%"
- id="text6635"
- y="160.39748"
- x="322.23865"
- style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
- xml:space="preserve"><tspan
- y="160.39748"
- x="322.23865"
- id="tspan6637"
- sodipodi:role="line">API</tspan></text>
- <rect
- style="fill:#ff9955;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0"
- id="rect6575"
- width="66.670067"
- height="60.609154"
- x="428.80978"
- y="119.99139" />
- <path
- style="fill:#ff6600;fill-opacity:1;stroke:#faf6a2;stroke-width:1.98960423;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
- d="m 494.97474,119.62537 44.95179,-22.589454 0,57.373054 -44.95179,26.69664 z"
- id="rect6595"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccccc" />
- <path
- style="fill:#ff6600;fill-opacity:1;stroke:#c48069;stroke-width:1.99399996;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
- d="m 473.25645,97.26295 66.67007,10e-7 -44.95179,22.728439 -66.16499,0 z"
- id="rect6612"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccccc" />
- <text
- xml:space="preserve"
- style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
- x="439.41635"
- y="159.89241"
- id="text6639"
- sodipodi:linespacing="125%"><tspan
- sodipodi:role="line"
- id="tspan6641"
- x="439.41635"
- y="159.89241">API</tspan></text>
- <g
- style="font-size:24px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
- id="text6643" />
- <text
- xml:space="preserve"
- style="font-size:24px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
- x="71.720833"
- y="95.747719"
- id="text6648"
- sodipodi:linespacing="125%"><tspan
- sodipodi:role="line"
- id="tspan6650"
- x="71.720833"
- y="95.747719" /></text>
- <text
- xml:space="preserve"
- style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
- x="176.77669"
- y="216.96603"
- id="text6652"
- sodipodi:linespacing="125%"><tspan
- sodipodi:role="line"
- id="tspan6654"
- x="176.77669"
- y="216.96603">Network Protocol</tspan></text>
- <text
- xml:space="preserve"
- style="font-size:36px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
- x="233.34526"
- y="312.93051"
- id="text6656"
- sodipodi:linespacing="125%"><tspan
- sodipodi:role="line"
- id="tspan6658"
- x="233.34526"
- y="312.93051">Service</tspan></text>
- <rect
- style="fill:#ffffff;fill-opacity:1;stroke:#faf6a2;stroke-width:2.09665918;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0"
- id="rect6660"
- width="66.670067"
- height="66.609154"
- x="216.67773"
- y="371.51938" />
- <rect
- y="371.51938"
- x="322.74374"
- height="64.373825"
- width="66.670067"
- id="rect6662"
- style="fill:#ffffff;fill-opacity:1;stroke:#faf6a2;stroke-width:2.06117821;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" />
- <rect
- style="fill:#ffffff;fill-opacity:1;stroke:#faf6a2;stroke-width:2;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0"
- id="rect6664"
- width="66.670067"
- height="60.609154"
- x="423.75903"
- y="372.52951" />
- <path
- sodipodi:nodetypes="ccccc"
- inkscape:connector-curvature="0"
- id="path6666"
- d="m 423.61996,372.56359 67.23534,-0.62641 0,19.59587 -68.24549,41.17879 z"
- style="fill:#ffcc00;fill-opacity:1;stroke:#faf6a2;stroke-width:0.98368376;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" />
- <path
- style="fill:#ffcc00;fill-opacity:1;stroke:#faf6a2;stroke-width:0.98368376;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
- d="m 322.60471,371.55344 67.23534,0.38374 0,23.63648 -67.23534,37.13818 z"
- id="path6668"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccccc" />
- <path
- sodipodi:nodetypes="ccccc"
- inkscape:connector-curvature="0"
- id="path6670"
- d="m 322.60471,371.55344 67.23534,0.38374 0,23.63648 -67.23534,37.13818 z"
- style="fill:#ffcc00;fill-opacity:1;stroke:#faf6a2;stroke-width:0.98368376;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" />
- <path
- style="fill:#ffcc00;fill-opacity:1;stroke:#faf6a2;stroke-width:0.98368376;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0"
- d="m 216.53869,371.55344 67.23534,0.38374 0,23.63648 -67.23534,37.13818 z"
- id="path6672"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccccc" />
- <text
- xml:space="preserve"
- style="font-size:32px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
- x="262.63965"
- y="666.48389"
- id="text6711"
- sodipodi:linespacing="125%"><tspan
- sodipodi:role="line"
- id="tspan6713"
- x="262.63965"
- y="666.48389" /></text>
- <rect
- y="371.51938"
- x="111.62187"
- height="70.798637"
- width="66.670067"
- id="rect6721"
- style="fill:#ffffff;fill-opacity:1;stroke:#faf6a2;stroke-width:2.1615901;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dasharray:none;stroke-dashoffset:0" />
- <path
- sodipodi:nodetypes="ccccc"
- inkscape:connector-curvature="0"
- id="path6723"
- d="m 111.48283,370.54329 67.23534,0.38374 0,23.63648 -67.23534,37.13818 z"
- style="fill:#ffcc00;fill-opacity:1;stroke:#faf6a2;stroke-width:0.98368376;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:0;stroke-dashoffset:0" />
- </g>
-</svg>
+++ /dev/null
-// house = application
-// circle (default) = service
-// box = daemon
-// diamond = library
-// black line = dependency
-// blue line = extension via plugin
-// red line = possibly useful
-// dashed = in planning
-
-// this is what we have...o
-digraph dependencies {
-splines = true;
-
- voting [shape=house];
- voting -> consensus;
- voting -> identity;
- voting -> cadet;
- voting -> secretsharing;
- secretsharing -> consensus;
-
- fs [shape=house];
- fs -> dht;
- fs -> core;
- fs -> datastore;
- fs -> cadet;
- fs -> ats;
- fs -> block [style=dotted,color=blue];
- fs -> identity;
- exit [shape=box];
- exit -> cadet;
- exit -> tun;
- exit -> dnsstub;
- vpn -> cadet;
- vpn -> regex;
- vpn -> tun;
- pt [shape=house];
- pt -> cadet;
- pt -> vpn;
- pt -> dns;
- pt -> dnsparser;
- dns -> tun;
- dns -> dnsstub;
- zonemaster [shape=house];
- zonemaster -> namestore;
- zonemaster -> dht;
- gns -> dns;
- gns -> dht;
- gns -> block [style=dotted,color=blue];
- gns -> revocation;
- gns -> vpn;
- gns -> dnsparser;
- gns -> dnsstub;
- gns -> identity;
- revocation -> core;
- revocation -> set;
- namestore -> identity;
- namestore -> gnsrecord;
- dnsparser -> gnsrecord [style=dotted,color=blue];
- conversation -> gnsrecord [style=dotted,color=blue];
- gns -> gnsrecord;
- dht -> core;
- dht -> nse;
- dht -> block;
- dht -> datacache;
- dht -> peerinfo;
- dht -> hello;
- nse -> core;
- regex -> block [style=dotted,color=blue];
- block [shape=diamond];
- datacache [shape=diamond];
- cadet -> core [weight=2];
- cadet -> dht;
- cadet -> block [style=dotted,color=blue];
- conversation [shape=house];
- conversation -> cadet;
- conversation -> gns;
- conversation -> speaker;
- conversation -> microphone;
- speaker [shape=diamond];
- microphone [shape=diamond];
- regex -> dht;
- core -> transport;
- topology [shape=box];
- topology -> peerinfo;
- topology -> transport;
- topology -> core;
- topology -> hello;
- hostlist [shape=box];
- hostlist -> core;
- hostlist -> peerinfo;
- hostlist -> hello;
- transport -> ats;
- transport -> hello;
- transport -> peerinfo;
- transport -> nat;
- transport -> fragmentation;
- consensus -> set;
- consensus -> cadet;
- scalarproduct -> set;
- scalarproduct -> cadet;
- set -> cadet;
- peerinfo -> hello;
- fragmentation [shape=diamond];
- hello [shape=diamond];
- nat [shape=diamond];
- tun [shape=diamond];
- dnsparser [shape=diamond];
- dnsstub [shape=diamond];
-
- secushare [shape=house];
- multicast;
- psyc;
- social -> psyc;
- social -> gns;
- psyc -> psycstore;
- psycstore;
- social;
- secushare -> social;
- psyc -> multicast;
- multicast -> cadet;
-
- rps;
- rps -> core;
-}
+++ /dev/null
-#include <unistd.h>
-#include <gnunet/platform.h>
-#include <gnunet/gnunet_util_lib.h>
-#include <gnunet/gnunet_testbed_service.h>
-#include <gnunet/gnunet_dht_service.h>
-
-#define NUM_PEERS 20
-
-static struct GNUNET_TESTBED_Operation *dht_op;
-
-static struct GNUNET_DHT_Handle *dht_handle;
-
-
-struct MyContext
-{
- int ht_len;
-} ctxt;
-
-
-static int result;
-
-
-static void
-shutdown_task (void *cls)
-{
- if (NULL != dht_op)
- {
- GNUNET_TESTBED_operation_done (dht_op);
- dht_op = NULL;
- dht_handle = NULL;
- }
- result = GNUNET_OK;
-}
-
-
-static void
-service_connect_comp (void *cls,
- struct GNUNET_TESTBED_Operation *op,
- void *ca_result,
- const char *emsg)
-{
- GNUNET_assert (op == dht_op);
- dht_handle = ca_result;
- // Do work here...
- GNUNET_SCHEDULER_shutdown ();
-}
-
-
-static void *
-dht_ca (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg)
-{
- struct MyContext *ctxt = cls;
-
- dht_handle = GNUNET_DHT_connect (cfg, ctxt->ht_len);
- return dht_handle;
-}
-
-
-static void
-dht_da (void *cls, void *op_result)
-{
- struct MyContext *ctxt = cls;
-
- GNUNET_DHT_disconnect ((struct GNUNET_DHT_Handle *) op_result);
- dht_handle = NULL;
-}
-
-
-static void
-test_master (void *cls,
- struct GNUNET_TESTBED_RunHandle *h,
- unsigned int num_peers,
- struct GNUNET_TESTBED_Peer **peers,
- unsigned int links_succeeded,
- unsigned int links_failed)
-{
- ctxt.ht_len = 10;
- dht_op = GNUNET_TESTBED_service_connect
- (NULL, peers[0], "dht",
- &service_connect_comp, NULL,
- &dht_ca, &dht_da, &ctxt);
- GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL);
-}
-
-
-int
-main (int argc, char **argv)
-{
- int ret;
-
- result = GNUNET_SYSERR;
- ret = GNUNET_TESTBED_test_run
- ("awesome-test", "template.conf",
- NUM_PEERS, 0LL,
- NULL, NULL, &test_master, NULL);
- if ( (GNUNET_OK != ret) || (GNUNET_OK != result) )
- return 1;
- return 0;
-}
+++ /dev/null
-#include <gnunet/platform.h>
-#include <gnunet/gnunet_util_lib.h>
-
-static int ret;
-
-static void
-run (void *cls,
- char *const *args,
- const char *cfgfile,
- const struct GNUNET_CONFIGURATION_Handle *cfg)
-{
- // main code here
- ret = 0;
-}
-
-int
-main (int argc, char *const *argv)
-{
- struct GNUNET_GETOPT_CommandLineOption options[] = {
- GNUNET_GETOPT_OPTION_END
- };
- return (GNUNET_OK ==
- GNUNET_PROGRAM_run (argc,
- argv,
- "binary-name",
- gettext_noop ("binary description text"),
- options, &run, NULL)) ? ret : 1;
-}
-
+++ /dev/null
-static char *string_option;
-static int a_flag;
-
-// ...
- struct GNUNET_GETOPT_CommandLineOption options[] = {
- GNUNET_GETOPT_option_string ('s', "name", "SOMESTRING",
- gettext_noop ("text describing the string_option NAME"),
- &string_option},
- GNUNET_GETOPT_option_flag ('f', "flag",
- gettext_noop ("text describing the flag option"),
- &a_flag),
- GNUNET_GETOPT_OPTION_END
- };
- string_option = NULL;
- a_flag = GNUNET_SYSERR;
-// ...
-
+++ /dev/null
-struct GNUNET_MQ_MessageHandlers handlers[] = {
- // ...
- GNUNET_MQ_handler_end ()
-};
-struct GNUNET_MQ_Handle *mq;
-
-mq = GNUNET_CLIENT_connect (cfg,
- "service-name",
- handlers,
- &error_cb,
- NULL);
+++ /dev/null
-struct GNUNET_MessageHeader
-{
- uint16_t size GNUNET_PACKED;
- uint16_t type GNUNET_PACKED;
-};
+++ /dev/null
-struct GNUNET_MQ_Envelope *env;
-struct GNUNET_MessageHeader *msg;
-
-env = GNUNET_MQ_msg_extra (msg, payload_size, GNUNET_MY_MESSAGE_TYPE);
-memcpy (&msg[1], &payload, payload_size);
-// Send message via message queue 'mq'
-GNUNET_mq_send (mq, env);
-
+++ /dev/null
-static void
-handle_fix (void *cls, const struct MyMessage *msg)
-{
- // process 'msg'
-}
-
-static int
-check_var (void *cls, const struct MyVarMessage *msg)
-{
- // check 'msg' is well-formed
- return GNUNET_OK;
-}
-
-static void
-handle_var (void *cls, const struct MyVarMessage *msg)
-{
- // process 'msg'
-}
-
-struct GNUNET_MQ_MessageHandler handlers[] = {
- GNUNET_MQ_hd_fixed_size (fix,
- GNUNET_MESSAGE_TYPE_MY_FIX,
- struct MyMessage,
- NULL),
- GNUNET_MQ_hd_fixed_size (var,
- GNUNET_MESSAGE_TYPE_MY_VAR,
- struct MyVarMessage,
- NULL),
-
- GNUNET_MQ_handler_end ()
-};
+++ /dev/null
-GNUNET_SERVICE_MAIN
-("service-name",
- GNUNET_SERVICE_OPTION_NONE,
- &run,
- &client_connect_cb,
- &client_disconnect_cb,
- NULL,
- GNUNET_MQ_hd_fixed_size (...),
- GNUNET_MQ_hd_var_size (...),
- GNUNET_MQ_handler_end ());
+++ /dev/null
-static void
-run (void *cls,
- const struct GNUNET_CONFIGURATION_Handle *c,
- struct GNUNET_SERVICE_Handle *service)
-{
-}
-
-static void *
-client_connect_cb (void *cls,
- struct GNUNET_SERVICE_Client *c,
- struct GNUNET_MQ_Handle *mq)
-{
- return c;
-}
-
-static void
-client_disconnect_cb (void *cls,
- struct GNUNET_SERVICE_Client *c,
- void *internal_cls)
-{
- GNUNET_assert (c == internal_cls);
-}
+++ /dev/null
-#include <gnunet/gnunet_core_service.h>
-
-struct GNUNET_CORE_Handle *
-GNUNET_CORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
- void *cls,
- GNUNET_CORE_StartupCallback init,
- GNUNET_CORE_ConnectEventHandler connects,
- GNUNET_CORE_DisconnectEventHandler disconnects,
- const struct GNUNET_MQ_MessageHandler *handlers);
+++ /dev/null
-void *
-connects (void *cls,
- const struct GNUNET_PeerIdentity *peer,
- struct GNUNET_MQ_Handle *mq)
-{
- return mq;
-}
-
+++ /dev/null
-void
-disconnects (void *cls,
- const struct GNUNET_PeerIdentity * peer)
-{
- /* Remove peer's identity from known peers */
- /* Make sure no messages are sent to peer from now on */
-}
-
+++ /dev/null
-#include "gnunet_peerstore_service.h"
-
-peerstore_handle = GNUNET_PEERSTORE_connect (cfg);
-
+++ /dev/null
-void
-GNUNET_PEERSTORE_store_cancel (struct GNUNET_PEERSTORE_StoreContext
- *sc);
+++ /dev/null
-struct GNUNET_PEERSTORE_StoreContext *
-GNUNET_PEERSTORE_store (struct GNUNET_PEERSTORE_Handle *h,
- const char *sub_system,
- const struct GNUNET_PeerIdentity *peer,
- const char *key,
- const void *value,
- size_t size,
- struct GNUNET_TIME_Absolute expiry,
- enum GNUNET_PEERSTORE_StoreOption options,
- GNUNET_PEERSTORE_Continuation cont,
- void *cont_cls);
-
+++ /dev/null
-struct GNUNET_PEERSTORE_IterateContext *
-GNUNET_PEERSTORE_iterate (struct GNUNET_PEERSTORE_Handle *h,
- const char *sub_system,
- const struct GNUNET_PeerIdentity *peer,
- const char *key,
- struct GNUNET_TIME_Relative timeout,
- GNUNET_PEERSTORE_Processor callback,
- void *callback_cls);
-
+++ /dev/null
-struct GNUNET_PEERSTORE_WatchContext *
-GNUNET_PEERSTORE_watch (struct GNUNET_PEERSTORE_Handle *h,
- const char *sub_system,
- const struct GNUNET_PeerIdentity *peer,
- const char *key,
- GNUNET_PEERSTORE_Processor callback,
- void *callback_cls);
-
+++ /dev/null
-void
-GNUNET_PEERSTORE_watch_cancel (struct GNUNET_PEERSTORE_WatchContext
- *wc);
-
+++ /dev/null
-void
-GNUNET_PEERSTORE_disconnect (struct GNUNET_PEERSTORE_Handle *h,
- int sync_first);
-
+++ /dev/null
-dht_handle = GNUNET_DHT_connect (cfg, parallel_requests);
-
+++ /dev/null
-message_sent_cont (void *cls,
- const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- // Request has left local node
-}
-
-struct GNUNET_DHT_PutHandle *
-GNUNET_DHT_put (struct GNUNET_DHT_Handle *handle,
- const struct GNUNET_HashCode *key,
- uint32_t desired_replication_level,
- enum GNUNET_DHT_RouteOption options,
- enum GNUNET_BLOCK_Type type,
- size_t size,
- const void *data,
- struct GNUNET_TIME_Absolute exp,
- struct GNUNET_TIME_Relative timeout,
- GNUNET_DHT_PutContinuation cont, void *cont_cls)
-
+++ /dev/null
-static void
-get_result_iterator (void *cls, struct GNUNET_TIME_Absolute expiration,
- const struct GNUNET_HashCode *key,
- const struct GNUNET_PeerIdentity *get_path,
- unsigned int get_path_length,
- const struct GNUNET_PeerIdentity *put_path,
- unsigned int put_path_length,
- enum GNUNET_BLOCK_Type type, size_t size,
- const void *data)
-{
- // Optionally:
- GNUNET_DHT_get_stop (get_handle);
-}
-
-get_handle =
- GNUNET_DHT_get_start (dht_handle,
- block_type,
- &key,
- replication,
- GNUNET_DHT_RO_NONE,
- NULL,
- 0,
- &get_result_iterator,
- cls)
-
+++ /dev/null
-static enum GNUNET_BLOCK_EvaluationResult
-block_plugin_SERVICE_evaluate (void *cls,
- enum GNUNET_BLOCK_Type type,
- struct GNUNET_BlockGroup *bg,
- const GNUNET_HashCode *query,
- const void *xquery,
- size_t xquery_size,
- const void *reply_block,
- size_t reply_block_size)
-{
- // Verify type, block and bg
-}
-
+++ /dev/null
-static int
-block_plugin_SERVICE_get_key (void *cls, enum GNUNET_BLOCK_Type type,
- const void *block, size_t block_size,
- struct GNUNET_HashCode *key)
-{
- // Store the key in the key argument, return GNUNET_OK on success.
-}
-
+++ /dev/null
-void *
-libgnunet_plugin_block_SERVICE_init (void *cls)
-{
- static enum GNUNET_BLOCK_Type types[] =
- {
- GNUNET_BLOCK_TYPE_SERVICE_BLOCKYPE,
- GNUNET_BLOCK_TYPE_ANY
- };
- struct GNUNET_BLOCK_PluginFunctions *api;
-
- api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions);
- api->evaluate = &block_plugin_SERICE_evaluate;
- api->get_key = &block_plugin_SERVICE_get_key;
- api->types = types;
- return api;
-}
-
+++ /dev/null
-void *
-libgnunet_plugin_block_SERVICE_done (void *cls)
-{
- struct GNUNET_TRANSPORT_PluginFunctions *api = cls;
-
- GNUNET_free (api);
- return NULL;
-}
-
+++ /dev/null
- plugindir = $(libdir)/gnunet
-
- plugin_LTLIBRARIES = \
- libgnunet_plugin_block_ext.la
- libgnunet_plugin_block_ext_la_SOURCES = \
- plugin_block_ext.c
- libgnunet_plugin_block_ext_la_LIBADD = \
- $(prefix)/lib/libgnunethello.la \
- $(prefix)/lib/libgnunetblock.la \
- $(prefix)/lib/libgnunetutil.la
- libgnunet_plugin_block_ext_la_LDFLAGS = \
- $(GN_PLUGIN_LDFLAGS)
- libgnunet_plugin_block_ext_la_DEPENDENCIES = \
- $(prefix)/lib/libgnunetblock.la
-
+++ /dev/null
-static void
-get_callback (void *cls,
- enum GNUNET_DHT_RouteOption options,
- enum GNUNET_BLOCK_Type type,
- uint32_t hop_count,
- uint32_t desired_replication_level,
- unsigned int path_length,
- const struct GNUNET_PeerIdentity *path,
- const struct GNUNET_HashCode * key)
-{
-}
-
-
-static void
-get_resp_callback (void *cls,
- enum GNUNET_BLOCK_Type type,
- const struct GNUNET_PeerIdentity *get_path,
- unsigned int get_path_length,
- const struct GNUNET_PeerIdentity *put_path,
- unsigned int put_path_length,
- struct GNUNET_TIME_Absolute exp,
- const struct GNUNET_HashCode * key,
- const void *data,
- size_t size)
-{
-}
-
-
-static void
-put_callback (void *cls,
- enum GNUNET_DHT_RouteOption options,
- enum GNUNET_BLOCK_Type type,
- uint32_t hop_count,
- uint32_t desired_replication_level,
- unsigned int path_length,
- const struct GNUNET_PeerIdentity *path,
- struct GNUNET_TIME_Absolute exp,
- const struct GNUNET_HashCode * key,
- const void *data,
- size_t size)
-{
-}
-
-
-monitor_handle = GNUNET_DHT_monitor_start (dht_handle,
- block_type,
- key,
- &get_callback,
- &get_resp_callback,
- &put_callback,
- cls);
-