gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnunet-scheme] 06/07: doc: Split relatively large chapters into separat


From: gnunet
Subject: [gnunet-scheme] 06/07: doc: Split relatively large chapters into separate files.
Date: Sun, 06 Feb 2022 10:53:29 +0100

This is an automated email from the git hooks/post-receive script.

maxime-devos pushed a commit to branch master
in repository gnunet-scheme.

commit 973d5cc3398ff7581173c8c784cc281d7a838c15
Author: Maxime Devos <maximedevos@telenet.be>
AuthorDate: Sat Feb 5 20:24:59 2022 +0000

    doc: Split relatively large chapters into separate files.
    
    This seems a bit tidier to me.
    
    * doc/scheme-gnunet.tm: Extract some chapters into ...
    * doc/configuration.tm: ... a separate file.
    * doc/contributing.tm: Likewise.
    * doc/distributed-hash-table.tm: Likewise.
    * doc/network-size-estimation.tm: Likewise.
    * doc/network-structures.tm: Likewise.
    * doc/service-communication.tm: Likewise.
    * Makefile.am (tm_fragments): New variable.
      (doc/sheme-gnunet.df,doc/scheme-gnunet.html): Add dependency
      information.
      (dist_doc_DATA): Install and distribute new files.
---
 .reuse/dep5                    |    2 +-
 Makefile.am                    |   11 +-
 doc/configuration.tm           |  185 +++++++
 doc/contributing.tm            |  150 ++++++
 doc/distributed-hash-table.tm  |  270 ++++++++++
 doc/network-size-estimation.tm |   81 +++
 doc/network-structures.tm      |  210 ++++++++
 doc/scheme-gnunet.tm           | 1138 +---------------------------------------
 doc/service-communication.tm   |  325 ++++++++++++
 9 files changed, 1237 insertions(+), 1135 deletions(-)

diff --git a/.reuse/dep5 b/.reuse/dep5
index dc0df22..34abeaa 100644
--- a/.reuse/dep5
+++ b/.reuse/dep5
@@ -7,7 +7,7 @@ Files: doc/fdl.tm
 Copyright: 2000 2001 2002 2007 2008 Free Software Foundation, Inc. 
<https://fsf.org>
 License: LicenseRef-Verbatim
 
-Files: doc/scheme-gnunet.tm
+Files: doc/configuration.tm doc/contributing.tm doc/distributed-hash-table.tm 
doc/network-size-estimation.tm doc/network-structures.tm 
doc/service-communication.tm doc/scheme-gnunet.tm 
 Copyright: 2021 2022 GNUnet e.V.
 License: GFDL-1.3-no-invariants-or-later
 
diff --git a/Makefile.am b/Makefile.am
index 6144608..e7ac0f3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -219,12 +219,17 @@ TEXMACS_HTML_SETTINGS = \
    (set-boolean-preference "texmacs->html:mathjax" \#f)\
    (set-boolean-preference "texmacs->html:mathml" \#t)'
 
-doc/scheme-gnunet.pdf: doc/scheme-gnunet.tm
+tm_fragments = \
+  doc/configuration.tm doc/contributing.tm doc/distributed-hash-table.tm \
+  doc/network-size-estimation.tm doc/network-structures.tm \
+  doc/service-communication.tm
+
+doc/scheme-gnunet.pdf: doc/scheme-gnunet.tm $(tm_fragments)
        $(TEXMACS_CONVERT) -c "$<" "$@" -q
-doc/scheme-gnunet.html: doc/scheme-gnunet.tm
+doc/scheme-gnunet.html: doc/scheme-gnunet.tm $(tm_fragments)
        $(TEXMACS_CONVERT) -x $(TEXMACS_HTML_SETTINGS) -c "$<" "$@" -q
 
-dist_doc_DATA = doc/scheme-gnunet.tm doc/fdl.tm
+dist_doc_DATA = doc/scheme-gnunet.tm $(tm_fragments) doc/fdl.tm
 nobase_dist_doc_DATA = examples/web.scm
 nodist_html_DATA = doc/scheme-gnunet.html
 nodist_pdf_DATA = doc/scheme-gnunet.pdf
diff --git a/doc/configuration.tm b/doc/configuration.tm
new file mode 100644
index 0000000..3ac8261
--- /dev/null
+++ b/doc/configuration.tm
@@ -0,0 +1,185 @@
+<TeXmacs|2.1>
+
+<project|scheme-gnunet.tm>
+
+<style|tmmanual>
+
+<\body>
+  There are a number of modules for accessing GNUnet
+  configurations<index|configuration>.<space|1em>Firstly, there is <scm|(gnu
+  gnunet config db)><index|(gnu gnunet config db)>, which is the module
+  library code would typically use.<space|1em>For testing, one can create an
+  empty configuration with the procedure 
<scm|hash-\<gtr\>configuration><index|hash-\<gtr\>configuration>
+  from that module and <scm|make-hashtable> from <scm|(rnrs hashtables)>,
+  using <scm|hash-key><index|hash-key> as hash function and
+  <scm|key=?><index|key=?> as comparison function:
+
+  <\scm-code>
+    (import (gnu gnunet config db)
+
+    \ \ \ \ \ \ \ \ (gnu gnunet config value-parser)
+
+    \ \ \ \ \ \ \ \ (rnrs hashtables))
+
+    (define config (hash-\<gtr\>configuration (make-hashtable hash-key
+    key=?))
+  </scm-code>
+
+  The resulting configuration <scm|config> is initially empty, so set some
+  <with|font-shape|italic|keys> in the <with|font-shape|italic|section>
+  <verbatim|nse>, to configure the network-size estimation service:
+
+  <\scm-code>
+    (set-value! identity config "nse" "UNIXPATH"
+    "/tmp/nse.sock")<index|set-value!>
+
+    (set-value! number-\<gtr\>string config "cadet" "MAX_ROUTES" 5000)
+
+    ;; TODO: IP address, time durations, booleans, ...
+  </scm-code>
+
+  Now read these values back:
+
+  <\scm-code>
+    (read-value value-\<gtr\>file-name config "nse"
+    "UNIXPATH")<index|read-value>
+
+    ;; -\<gtr\> /tmp/nse.sock
+
+    (read-value value-\<gtr\>natural config "cadet" "MAX_ROUTES")
+
+    ;; -\<gtr\> 5000
+  </scm-code>
+
+  What if the configuration doesn't have a value for the specified section
+  and key?<space|1em>Then an 
<scm|&undefined-key-error><index|&undefined-key-error>
+  results:
+
+  <\scm-code>
+    (read-value value-\<gtr\>natural config "kated" "MAX_ROUTES")
+
+    ;; -\<gtr\>
+
+    ;; ice-9/boot-9.scm:1685:16: In procedure raise-exception:
+
+    ;; ERROR:
+
+    ;; \ \ 1. &undefined-key-error:
+
+    ;; \ \ \ \ \ \ section: "kated"
+
+    ;; \ \ \ \ \ \ key: "MAX_ROUTES"
+  </scm-code>
+
+  <section|Locating configuration files>
+
+  There are two \U possibly non-existent \U configuration files: the
+  <with|font-shape|italic|user> configuration<subindex|configuration|user>
+  and the <with|font-shape|italic|system>
+  configuration<subindex|configuration|system>.<space|1em>The
+  <with|font-shape|italic|system> configuration typically contains the paths
+  for services like NSE, CORE, <text-dots><space|1em>A user may choose not to
+  use the services by the system and instead use their own.<space|1em>To do
+  so, the user needs to override the paths in the
+  <with|font-shape|italic|user> configuration.<space|1em><todo|defaults?> The
+  module <scm|(gnu gnunet config fs)><index|(gnu gnunet config fs)> is
+  responsible for determining the location of the configuration files to load
+  and actually load configuration files.<space|1em>For determining the
+  location of the configuration files, the procedures
+  <scm|locate-user-configuration> and <scm|locate-system-configuration> can
+  be used.
+
+  <\warning>
+    The C implementation's mechanism for user-system separation seems to work
+    differently.
+  </warning>
+
+  <\explain>
+    <scm|(locate-user-configuration 
<scm|#:getenv=getenv>)><index|locate-user-configuration>
+  <|explain>
+    This procedure determines the location of the user configuration file, as
+    a string, or <scm|#false> if it could not be determined.<space|1em>If the
+    location of the user configuration file is known, but the file does not
+    exist, it is returned anyway, as a string.
+
+    If the environment variable <shell|XDG_CONFIG_HOME> is set, the location
+    of the file <verbatim|gnunet.conf> in the directory
+    <shell|$XDG_CONFIG_HOME> is returned.<space|1em>If the environment
+    variable is not set, the location of the file at
+    <verbatim|.config/gnunet.conf><index|~/.config/gnunet.conf> in the home
+    directory specified by the environment variable <verbatim|HOME> is
+    returned, if that environment variable exists.<space|1em>If both are
+    unset, <scm|#false> is returned.
+
+    The values of environment variables is determined with the procedure
+    <scm|getenv>.
+  </explain>
+
+  <\explain>
+    <scm|(locate-system-configuration)><index|locate-system-configuration>
+  <|explain>
+    This procedure determines the location of the system configuration file,
+    as a string.
+
+    Currently, this is always 
<verbatim|/etc/gnunet.conf><index|/etc/gnunet.conf>.
+  </explain>
+
+  <section|Loading configuration files>
+
+  Once the location of the configuration file is known, the file can be
+  opened with the Scheme procedure <scm|open-input-file>, which returns an
+  input port.<space|1em>Then the procedure <scm|load-configuration/port!> can
+  be used to determine all section-key-values triples in the configuration.
+
+  <\explain>
+    <scm|(load-configuration/port! <var|set-value!>
+    <var|port>)><index|load-configuration/port!>
+  <|explain>
+    Load the configuration from the input port <var|port>.
+
+    For each variable, call <var|set-value!> with the section name, variable
+    name and a vector of the form <scm|#(line line-number value)>, where
+    <var|value> a list of expansible objects.
+
+    <todo|document expansible objects><todo|error reporting>
+  </explain>
+
+  A variable assignment<index|variable assignment> <verbatim|[section]
+  key=value${var}> can refer to variables defined in the <verbatim|PATHS>
+  section and variables from the environment.<space|1em>The previously
+  described procedure <scm|load-configuration/port!> will <em|not> expand
+  such assignements. \ To expand variable assignments, use the procedure
+  <scm|make-expanded-configuration> instead.
+
+  <\explain>
+    <scm|(make-expanded-configuration <var|load!>
+    #:getenv=<var|getenv>)><index|make-expanded-configuration>
+  <|explain>
+    Make a configuration object.<space|1em>To populate the configuration, all
+    the procedure <var|load!> with a <scm|set-value!> procedure as expected
+    by <scm|load-configuration/port!>.<space|1em>The values from
+    <scm|set-value!> are added to the confoiguration and every variable is
+    expanded.
+  </explain>
+
+  To automatically load the defaults, the system configuration and the user
+  configuration, use the thunk <scm|load-configuration>:
+
+  <\explain>
+    <scm|(load-configuration #:getenv=<var|getenv>
+    #:files=<text-dots>)><index|load-configuration>
+  </explain|Load the defaults, the system configuration and the user
+  configuration and return the resulting configuration object.<space|1em>The
+  list of files to load can be overriden by setting the undocumented
+  <var|files> keyword argument.>
+
+  Applications (whether graphical or textual) are recommended to use
+  <scm|load-configuration> by default, as it largely just works.
+</body>
+
+<\initial>
+  <\collection>
+    <associate|page-medium|paper>
+    <associate|save-aux|false>
+  </collection>
+</initial>
\ No newline at end of file
diff --git a/doc/contributing.tm b/doc/contributing.tm
new file mode 100644
index 0000000..724530f
--- /dev/null
+++ b/doc/contributing.tm
@@ -0,0 +1,150 @@
+<TeXmacs|2.1>
+
+<project|scheme-gnunet.tm>
+
+<style|generic>
+
+<\body>
+  <section|Building from source>
+
+  The latest \<#2018\>official\<#2019\> development version of scheme-GNUnet
+  can be found at 
<hlink|https://git.gnunet.org/gnunet-scheme.git/|https://git.gnunet.org/gnunet-scheme.git/>.
+  It can be downloaded with <hlink|git|https://en.wikipedia.org/wiki/Git>.
+  The following software needs to be installed first:
+
+  <\itemize>
+    <item>The Autotools 
(<hlink|autoconf|https://www.gnu.org/software/autoconf/>
+    and <hlink|automake|https://www.gnu.org/software/automake/>)
+
+    <item><hlink|GNU Guile|https://www.gnu.org/software/guile/> (at least
+    version 3), with the patch from 
<slink|https://debbugs.gnu.org/cgi/bugreport.cgi?bug=49623>
+    applied
+
+    <item><hlink|Purely Functional Data Structures in Scheme
+    (pfds)|https://github.com/ijp/pfds/>
+
+    <item><hlink|(Guile) Fibers|https://github.com/wingo/fibers/>, with the
+    <slink|https://github.com/wingo/fibers/pull/50> patch
+
+    
<item><hlink|Guile-QuickCheck|https://ngyro.com/software/guile-quickcheck.html>
+
+    <item><hlink|Guile-Gcrypt|https://notabug.org/cwebber/guile-gcrypt>
+  </itemize>
+
+  Users of <hlink|GNU Guix|https://guix.gnu.org><index|Guix> can run
+  <shell|guix shell -D gnunet-scheme> in the checkout to create an
+  environment where these dependencies are all
+  present.<space|1em>Scheme-GNUnet uses the standard GNU build system, so to
+  build Scheme-Gnunet, you only need to run
+
+  <\shell-code>
+    autoreconf -vif
+
+    ./configure
+
+    make
+
+    make check
+  </shell-code>
+
+  After building, the documentation is available at
+  <verbatim|doc/scheme-gnunet.pdf> and <verbatim|doc/scheme-gnunet.html> in
+  PDF and HTML formats.<space|1em>To get started, you can run the example
+  mini-application at <verbatim|examples/nse-web.scm> and point your browser
+  at <slink|http://localhost:8089>:
+
+  <\shell-code>
+    $ guile -L . -C . -l examples/nse-web.scm
+  </shell-code>
+
+  <subsection|Authenticating new source code><index|authentication>
+
+  When GNU Guix is present, after pulling the latest Scheme-GNUnet commit,
+  the following command can be run to verify it is authentic:
+
+  <\shell-code>
+    guix git authenticate 088ea8b27b95143584cbc36202c5a02dfe95796c "C1F3 3EE2
+    0C52 8FDB 7DD7 \ 011F 49E3 EE22 1917 25EE"
+  </shell-code>
+
+  If it isn't authentic, an error message such as the following will be
+  written:
+
+  <\shell-code>
+    Authenticating commits 54a74dc to 431f336 (1 new commits)...
+
+    [#########################################################]
+
+    guix git: error: commit 431f336edd51e1f0fe059a6f6f2d4c3e9267b7bc not
+    signed by an authorized key: C1F3 3EE2 0C52 8FDB 7DD7 \ 011F 49E3 EE22
+    1917 25EE
+  </shell-code>
+
+  <section|Writing tests>
+
+  <index|tests>\<#2018\><hlink|How SQLite Is
+  Tested|https://sqlite.org/testing.html>\<#2019\> is a recommended
+  read.<space|1em>Scheme-GNUnet isn't that well-tested but still aims for
+  being free of bugs and having many tests to prevents bugs from being
+  introduced.<space|1em>When adding new code, consider writing test
+  cases.<space|1em>Some things that can be tested and few methods for testing
+  things:
+
+  <\itemize>
+    <item>Run mutation tests.<space|1em>That is, replace in the source code
+    <scm|\<less\>> with <scm|\<less\>=>, <scm|0> with <scm|1>, a variable
+    reference <scm|i> with a variable reference <scm|j>, swap destination and
+    source arguments <text-dots> and verify whether the tests detect these
+    little mutations.
+
+    <item>Be exhaustive.<space|1em>If a procedure handles both foos and bars,
+    write test cases that pass the procedure a foo and test cases that pass
+    the procedure a bar.<space|1em>Sometimes Guile-QuickCheck can help with
+    generating many test cases if the input has a regular structure yet many
+    edge cases, see e.g. <verbatim|tests/cmsg.scm>.
+
+    <item>Verify exception mechanisms!<space|1em>If a procedure is expected
+    to handle I/O errors, simulate I/O errors and end-of-files in all the
+    wrong places.<space|1em>If the procedure can raise exceptions, make sure
+    these exceptions are raised when necessary.
+  </itemize>
+
+  Tests are added in the directory <scm|tests> and to the variable
+  <verbatim|SCM_TESTS> in <verbatim|Makefile.am> and use <scm|srfi
+  :64>.<space|1em>To run the test suite, run <verbatim|make check>.
+
+  <section|Contact>
+
+  Scheme-GNUnet is currently maintained on NotABug:
+  <slink|https://notabug.org/maximed/scheme-gnunet/>.<space|1em>Issues and
+  pull requests can be reported and submitted here.<space|1em>Alternatively,
+  for discussion about developing Scheme-GNUnet, you can send mails to
+  <hlink|gnunet-devel@gnu.org|mailto:gnunet-devel@gnu.org> and for help about
+  how to use Scheme-GNUnet, you can contact
+  <hlink|help-gnunet@gnu.org|mailto:help-gnunet@gnu.org>.<space|1em>These are
+  public mailing lists, so don't send anything there you wouldn't mind the
+  whole world to know.
+
+  For security-sensitive issues, you can send a mail directly to the
+  maintainer, <hlink|Maxime Devos 
\<less\>maximedevos@telenet.be\<gtr\>|mailto:maximedevos@telenet.be>,
+  optionally encrypted and signed with a GnuPG-compatible
+  system.<space|1em>The maintainer's key fingerprint is C1F3 3EE2 0C52 8FDB
+  7DD7 011F 49E3 EE22 1917 25EE and a copy of the key can be downloaded from
+  <slink|https://notabug.org/maximed/things/raw/master/Maxime_Devos.pub>.
+
+  <section|License>
+
+  The code of Scheme-GNUnet is available under the Affero General Public
+  License (AGPL), version 3 or later; see individual source files for
+  details.<space|1em>The documentaton is available under the GNU Free
+  Documentation License, see the start of this manual and the likewise-named
+  appendix for details.<space|1em>The AGPL has some unusual conditions w.r.t.
+  applications interacting with the network, please read it carefully.
+</body>
+
+<\initial>
+  <\collection>
+    <associate|page-medium|paper>
+    <associate|save-aux|false>
+  </collection>
+</initial>
\ No newline at end of file
diff --git a/doc/distributed-hash-table.tm b/doc/distributed-hash-table.tm
new file mode 100644
index 0000000..b9f25fe
--- /dev/null
+++ b/doc/distributed-hash-table.tm
@@ -0,0 +1,270 @@
+<TeXmacs|2.1>
+
+<project|scheme-gnunet.tm>
+
+<style|tmmanual>
+
+<\body>
+  GNUnet has a service that maintains a <em|distributed hash
+  table><index|distributed hash table><index|DHT><index|R5N>, mapping keys to
+  values. The module <scm|(gnu gnunet dht client)><index|(gnu gnunet dht
+  client)> can be used to interact with the service. The connection can be
+  made with the procedure <scm|connect>. It returns a <em|DHT server
+  object><index|DHT server object><subindex|server object|DHT>.
+
+  <\explain>
+    <scm|(connect <var|config> <var|#:connected> <var|#:disconnected>
+    <var|#:spawn>)><subindex|connect|DHT>
+  <|explain>
+    Connect to the DHT service, using the configuration <var|config>. The
+    connection is made asynchronuously; the optional thunk <var|connected> is
+    called when the connection has been made. The connection can break; the
+    optional thunk <var|disconnected> is called when it does. If the
+    connection breaks, the client code automatically tries to reconnect, so
+    <var|connected> can be called after <var|disconnected>.
+  </explain>
+
+  <\explain>
+    <scm|(disconnect! <var|server>)><subindex|disconnect!|DHT>
+  <|explain>
+    Asynchronuously disconnect from the DHT service and stop reconnecting,
+    even if not connected. This is an idempotent operation.
+  </explain>
+
+  <section|Data in the DHT>
+
+  To insert data into the DHT, the DHT service needs various information \U
+  the key and the value, but also some other information. Likewise, when the
+  DHT service has found the datum, this information is available as well. A
+  datum in the DHT is represented as a <em|datum object><index|datum object>.
+  The object holding the information required for inserting something in the
+  DHT is called an <em|insertion object><index|insertion object>. Likewise,
+  the information of searching for something in the DHT is in a <em|query
+  object><index|query object>. The result of a query is a <em|search result
+  object><index|search result object>.
+
+  These objects only hold information; creating them does not have any side
+  effects.
+
+  <\explain>
+    <scm|(make-datum <var|type> <var|key> <var|value>
+    <var|#:expiration>)><index|make-datum>
+  <|explain>
+    Make a datum object of block type <var|type> (or its corresponding
+    numeric value), with key <var|key> (a readable <scm|/hashcode:512>
+    bytevector slice), value <var|value> (a readable bytevector slice) and
+    expiring at <var|expiration> (<todo|type, epoch>). The keyword argument
+    <var|expiration> is optional, see <reference|???>.
+
+    The numeric value of the block type can be retrieved with the accessor
+    <scm|datum-type>. The accessors <scm|datum-key><index|datum-key>,
+    <scm|datum-value><index|datum-value> and
+    <scm|datum-expiration><index|datum-expiration> return the key, value and
+    expiration time respectively. It can be tested if an object is a datum
+    object with the predicate <scm|datum?><index|datum?>.
+
+    The length of <var|value> may be at most
+    <scm|%max-datum-value-length><index|%max-datum-value-length>. If this
+    bound is exceeded, an appropriate 
<scm|&overly-large-datum><index|&overly-large-datum>
+    and <scm|&who> condition is raised.
+  </explain>
+
+  <\explain>
+    <scm|(datum-\<gtr\>insertion <var|datum>
+    #:desired-replication-level)><index|datum-\<gtr\>insertion>
+  <|explain>
+    Make an insertion object for inserting the datum <var|datum>, desiring a
+    replication level <var|desired-replication-level> (see
+    <reference|replication levels???>)<todo|various options>.
+
+    The datum and desired replication level can be recovered with the
+    accessors <scm|insertion-\<gtr\>datum><index|insertion-\<gtr\>datum> and
+    
<var|insertion-desired-replication-level><index|insertion-desired-replication-level>.
+    It can be tested if an object is an insertion object with the predicate
+    <scm|insertion?><index|insertion?>.
+  </explain>
+
+  <\explain>
+    <scm|(make-query <var|type> <var|key>
+    #:desired-replication-level)><index|make-query>
+  <|explain>
+    Make a query object for searching for a value of block type <var|type>
+    (or its corresponding numeric value), with key <var|key> (a readable
+    <scm|/hashcode:512> bytevector slice), at desired replication level
+    <scm|desired-replication-level> (see <reference|replication levels???>).
+    <todo|various options, xquery>
+
+    The numeric value of the block type, the key and the desired replication
+    level can be recovered with the accessors
+    <scm|query-type><index|query-type>, <scm|query-key><index|query-key> and
+    
<scm|query-desired-replication-level><index|query-desired-replication-level>.
+    It can be tested if an object is a query object with the predicate
+    <scm|query?><index|query?>.
+  </explain>
+
+  <\explain>
+    <scm|(datum-\<gtr\>search-result <var|datum> #:get-path
+    #:put-path)><index|datum-\<gtr\>search-result>
+  <|explain>
+    Make a search result object for the datum <var|datum>. The datum can be
+    recovered with the accessor 
<scm|search-result-\<gtr\>datum><index|search-result-\<gtr\>datum>.
+    It can be tested if an object is a search result with the predicate
+    <scm|search-result?><index|search-result?>. The optional arguments
+    <var|get-path> and <var|put-path>, when not false, are bytevector slices
+    consisting of a list of 
<scm|/dht:path-element><index|/dht:path-element><index|path
+    element>.
+
+    The <var|get-path><index|get path> , if any, is the path from the storage
+    location to the current peer. Conversely, the <var|put-path><index|put
+    path>, if any, is a path from the peer that inserted the datum into the
+    DHT to the storage location. The <var|get-path> and <var|put-path> can be
+    accessed with <scm|search-result-get-path><index|search-result-get-path>
+    and <scm|search-result-put-path><index|search-result-put-path>
+    respectively.
+
+    When the datum, get path and put path together are too large, a
+    <scm|&overly-large-paths><index|&overly-large-paths> condition is raised.
+    When the bytevector slice length of <var|get-path> or <var|put-path> is
+    not a multiple of the size of a path element, then a
+    <scm|&malformed-path><index|&malformed-path> condition is raised.
+  </explain>
+
+  <section|Accessing data in the DHT>
+
+  To insert a datum into the DHT, the procedure <scm|put!> is used. To find
+  data matching a query, the procedure <scm|start-get!> is
+  used.<index|searching the DHT><index|inserting data into the DHT>
+
+  <\explain>
+    <scm|(start-get! <var|server> <var|query> <var|found>)><index|start-get!>
+  <|explain>
+    Search for data matching <var|query> in the DHT. When a datum is found,
+    call the unary procedure <var|found> on the search result. It is possible
+    to find multiple data matching a query. In that case, <var|found> is
+    called multiple times. Searching happens asynchronuously; to stop the
+    search, a fresh <em|search object><index|search object> for controlling
+    the search is returned.
+
+    The procedure <var|found> is run from the context of <var|server>. As
+    such, if <var|found> blocks, then all operations on <var|server> might
+    block. As such, it is recommended for <var|found> to do as little as
+    possible by itself and instead delegate any work to a separate fiber.
+
+    To avoid expensive copies, the implementation can choose to reuse
+    internal buffers for the slices passed to <var|found>, which could be
+    overwritten after the call to <var|found>. As such, it might be necessary
+    to make a copy of the search result, using <scm|copy-search-result>.
+  </explain>
+
+  <\explain>
+    <scm|(put! <var|server> <var|insertion> <var|#:confirmed>)><index|put!>
+  <|explain>
+    Perform the insertion <var|insertion>. When the datum has been inserted,
+    the optional thunk <var|confirmed> is called. A <em|put object> is
+    returned which can be used to cancel the insertion.
+
+    <todo|TODO: actually call <var|confirmed>>
+  </explain>
+
+  <\explain>
+    <scm|(copy-query <var|old>)><index|copy-query>
+
+    <scm|(copy-datum <var|old>)><index|copy-datum>
+
+    <scm|(copy-insertion <var|old>)><index|copy-insertion>
+
+    <scm|(copy-search-result <var|old>)><index|copy-search-result>
+  <|explain>
+    Make a copy of the object <var|old> (a query, datum, insertion or search
+    result object, depending on the procedure), such that modifications to
+    the slices in <var|old> do not impact the new object.
+  </explain>
+
+  <todo|cancellation>
+
+  <section|Constructing and analysing network messages>
+
+  The DHT client and service communicate by sending <em|messages>. Usually,
+  only the implementation of the client and service need to construct and
+  analyse these messages, but nothing prevents other uses of the procedures
+  in <scm|(gnu gnunet dht network)><index|(gnu gnunet dht network)>, e.g. for
+  learning, in a tool like Wireshark or for tests.
+
+  The <em|analysis> procedures<index|analysis procedures> assume that the
+  message is well-formed and avoid constructing new bytevector slices by
+  taking subslices. The <em|construction> procedures<index|construction
+  procedures> create fresh well-formed read-write bytevector slices.
+
+  <\warning>
+    Possibly the type of <var|options> will change and possibly the options
+    will be moved into the query object and insertion object.
+  </warning>
+
+  <\explain>
+    <scm|(construct-client-get <var|query> <var|unique-id> #:optional
+    (<var|options> 0))><index|construct-client-get>
+  <|explain>
+    Create a new <scm|/:msg:dht:client:get><index|/:msg:dht:client:get>
+    message for the query object <var|query>, with <var|unique-id> as
+    \<#2018\>unique id\<#2019\> and <var|options> as options.
+  </explain>
+
+  <\explain>
+    <scm|(construct-client-put <var|insertion> #:optional (options
+    0))><index|construct-client-put>
+  <|explain>
+    Create a new <scm|/:msg:dht:client:put><index|/:msg:dht:client:put>
+    message for the insertion object <var|insertion> with <var|options> as
+    options.
+  </explain>
+
+  <\explain>
+    <scm|(construct-client-result <var|search-result>
+    <var|unique-id>)><index|construct-client-result>
+  <|explain>
+    Create a new <scm|/:msg:dht:client:result><index|/:msg:dht:client:result>
+    message for the search result object <var|search-result>, with
+    <var|unique-id> as \<#2018\>unique id\<#2019\> .
+  </explain>
+
+  <\explain>
+    <scm|(analyse-client-get <var|message>)><index|analyse-client-get>
+  <|explain>
+    Return the query object, the unique id and the options corresponding to
+    the <scm|/:msg:dht:client:result><index|/:msg:dht:client:result> message
+    <var|message>. Xqueries are currently unsupported.
+  </explain>
+
+  <\explain>
+    <scm|(analyse-client-put <var|message>)><index|analyse-client-put>
+  <|explain>
+    Return the insertion object and options corresponding to the
+    <scm|/:msg:dht:client:put><index|/:msg:dht:client:put> message
+    <var|message>.
+  </explain>
+
+  <\explain>
+    <scm|(analyse-client-result <var|message>)><index|analyse-client-result>
+  <|explain>
+    Return search result object and unique id for the
+    <scm|/:msg:dht:client:result><index|/:msg:dht:client:result> message
+    <var|message>.
+  </explain>
+
+  <todo|monitoring messages>
+
+  <section|How to handle invalid data>
+
+  <todo|todo!>
+
+  <section|Monitoring: spying on what other applications and peers are doing>
+
+  <todo|todo!>
+</body>
+
+<\initial>
+  <\collection>
+    <associate|page-medium|paper>
+    <associate|save-aux|false>
+  </collection>
+</initial>
\ No newline at end of file
diff --git a/doc/network-size-estimation.tm b/doc/network-size-estimation.tm
new file mode 100644
index 0000000..2be4361
--- /dev/null
+++ b/doc/network-size-estimation.tm
@@ -0,0 +1,81 @@
+<TeXmacs|2.1>
+
+<project|scheme-gnunet.tm>
+
+<style|tmmanual>
+
+<\body>
+  <index|network size estimation><index|NSE>GNUnet has a service that roughly
+  estimates the size of the network \U i.e., the number of
+  peers.<space|1em>The module <scm|(gnu gnunet nse client)><index|(gnu gnunet
+  nse client)> can be used to interact with this service.<space|1em>The
+  connection is made with the procedure <scm|connect><subindex|connect|NSE>,
+  which is accepts a <with|font-shape|italic|configuration> (see
+  <todo|reference>) and some optional keyword arguments.<space|1em>This
+  procedure can be called as <scm|(connect config #:updated updated
+  #:connected connected #:disconnected disconnected)>.<space|1em>It returns a
+  <with|font-shape|italic|NSE server object><index|NSE server
+  object><subindex|server object|NSE>.
+
+  The connection is made asynchronuously; the thunk <var|connected> will be
+  called when the connection has actually been made.<space|1em>Whenever a new
+  estimate becomes available, the (optional) procedure
+  <var|updated><index|update procedure> is called with the new
+  <with|font-shape|italic|estimate><index|estimate
+  object>.<space|1em>Alternatively, the procedure
+  <scm|estimate><index|estimate> can be called on the server object to return
+  the latest available estimate.<space|1em>If the
+  <with|font-shape|italic|server object> doesn't have an estimate yet, that
+  procedure will return <scm|#false> instead of an estimate.
+
+  When the connection is lost, the (optional) thunk <var|disconnected> is
+  called and <scm|(gnu gnunet nse client)> will retry
+  connecting.<space|1em>To close the current connection, if any, and stop
+  reconnecting, the idempotent procedure 
<scm|disconnect!><subindex|disconnect!|NSE>
+  can be called on the server object.
+
+  <todo|input, validation, I/O errors?>
+
+  The estimate object has a number of accessors:
+
+  <\explain>
+    <scm|(estimate:logarithmic-number-peers
+    <var|estimate>)><index|estimate:logarithmic-number-peers>
+  </explain|The base-2 logarithm of the number of peers (estimated), as a
+  positive flonum, possibly zero or infinite>
+
+  <\explain>
+    <scm|(estimate:number-peers <var|estimate>)><index|estimate:number-peeers>
+  </explain|The number of peers (estimated), as a flonum, at least <scm|1.0>
+  and possibly infinite.<space|1em>This is not necessarily an (inexact)
+  <scm|integer?>, as it is only an estimate.>
+
+  <\explain>
+    <scm|(estimate:timestamp estimate)><index|estimate:timestamp>
+  </explain|A timestamp when the estimate was made <todo|something about
+  epoch?>>
+
+  <\explain>
+    <scm|(estimate:standard-deviation 
<var|estimate>)><index|estimate:standard-deviation>
+  <|explain>
+    The estimated standard deviation on the base-2 logarithm of peers,
+    calculated over the last 64 rounds, with the <math|<frac|N|N-1>>
+    correction.<space|1em>This is a positive flonum, possibly zero or
+    infinite, or not-a-number (indicating division of zero by zero).
+
+    If the peer has been connected to the network for a while, the number is
+    expected to be finite and strictly positive.
+  </explain>
+
+  Assuming the network size is stable and the errors on the logarithmic
+  estimate are normally distributed, the procedure
+  <scm|estimate:standard-deviation> can be used to put probablistic error
+  bounds on the number of peers on the network. <todo|example>
+</body>
+
+<\initial>
+  <\collection>
+    <associate|page-medium|paper>
+    <associate|save-aux|false>
+  </collection>
+</initial>
\ No newline at end of file
diff --git a/doc/network-structures.tm b/doc/network-structures.tm
new file mode 100644
index 0000000..9a9941c
--- /dev/null
+++ b/doc/network-structures.tm
@@ -0,0 +1,210 @@
+<TeXmacs|2.1>
+
+<project|scheme-gnunet.tm>
+
+<style|tmmanual>
+
+<\body>
+  <index|network structure><index|netstruct>The modules <scm|(gnu gnunet
+  netstruct procedural)> and <scm|(gnu gnunet netstruct syntactic)> can be
+  used for formatting messages to be sent over the network or to a
+  service.<space|1em>The macros <scm|define-type><index|define-type> and
+  <scm|structure/packed><index|structure/packed> can be used to define new
+  structures, like this:
+
+  <\scm-code>
+    (define-type /:msg:nse:estimate/example
+
+    \ \ (structure/packed
+
+    \ \ \ (properties '((message-symbol msg:nse:estimate)))
+
+    \ \ \ (synopsis "Network size estimate")
+
+    \ \ \ (documentation "Some explanation")
+
+    \ \ \ (field (header /:message-header))
+
+    \ \ \ (field (size-estimate ieee-double/big)
+
+    \ \ \ \ \ \ \ \ \ \ (synopsis "Timestamp for when the estimate was
+    made"))))
+  </scm-code>
+
+  This example is taken from the <scm|(gnu gnunet nse struct)> module and
+  oversimplified.<space|1em>All its components will gradually
+  explained.<space|1em>First, what actually is a network
+  structure?<space|1em>This question is ambigious, because \<#2018\>network
+  structure\<#2019\> can refer to either the <with|font-shape|italic|value>
+  or the <with|font-shape|italic|type>.<space|1em>The
+  <with|font-shape|italic|value> is a sequence of octets, i.e., a sequence of
+  numbers in the closed range 0\U255.<space|1em>The
+  <with|font-shape|italic|type> describes how the
+  <with|font-shape|italic|value> is structured.
+
+  As an example, consider figure <reference|networkstructex>.<space|1em>There,
+  the value is <scm|0 12 1 65 64 51 238 123 71 27 58 149> and the type is
+  <scm|/:msg:nse:estimate/example>.
+
+  <big-figure|<tree|<scm|/:msg:nse:estimate/example>|<tree|<scm|header>
+  <scm|/:message-header>|<tree|<scm|size> <scm|u16/big>|0
+  12>|<tree|<scm|type> <scm|u16/big>|1 65>>|<tree|<scm|size-estimate>
+  <scm|ieee-double/big>|64 51 238 123 71 27 58 149>>|A network structure,
+  both <with|font-shape|italic|value> and
+  <with|font-shape|italic|type>.<label|networkstructex>>
+
+  This value has a <with|font-shape|italic|header> with a
+  <with|font-shape|italic|size> \<#2018\>0 0 0 12\<#2019\> of type
+  <scm|u32/big>, so the <with|font-shape|italic|size> is 12.<space|1em>The
+  <with|font-shape|italic|header> also has a <with|font-shape|italic|type>
+  \<#2018\>0 0 1 65\<#2019\> of type <scm|u32/big>, so the type is
+  <math|256\<times\>1+65=321>.<space|1em>The value also has a
+  <with|font-shape|italic|size estimate> of type
+  <scm|ieee-double/big>.<space|1em>The octets <scm|64 51 238 123 71 27 58
+  149>, \ interpreted as an IEEE double, form the number
+  <math|19.93\<ldots\>>.
+
+  <section|Documentation>
+
+  A network structure can optionally have embedded
+  documentation.<space|1em>More specifically, network structures can
+  optionally have the <with|font-shape|italic|synopsis><index|synopsis>,
+  <with|font-shape|italic|documentation><index|documentation> and
+  <with|font-shape|italic|properties><index|properties> set.<space|1em>The
+  <with|font-shape|italic|synopsis> is a short description of what the
+  network structure represents, typically a one-liner.<space|1em>The
+  <with|font-shape|italic|documentation> can be more detailed, explaining how
+  the structure works, can be used, is used and should be used.<space|1em>The
+  <with|font-shape|italic|properties> form a free-formed association list.
+
+  The synopsis, documentation and properties can be set on structured created
+  with <scm|structure/packed> and individual fields and can be accessed with
+  the procedures <scm|documentation>, <scm|synopsis> and <scm|properties>.
+
+  The following properties are defined in Scheme-GNUnet:
+
+  <\description>
+    <\item*>
+      <\code>
+        message-symbol
+      </code>
+    </item*>
+
+    <index|message-symbol>For <with|font-shape|italic|message structures>,
+    this is a list of the names of the <with|font-shape|italic|message types>
+    (see <reference|sec:message type> Message type database) this structure
+    can be used for \U most of the time, there's only a single such message
+    type, but sometimes a single structure can be used for multiple message
+    types.
+
+    <item*|c-type>
+
+    <label|c-type>The value is the name of the equivalent type in the C
+    implementation, if any, as a symbol. This can be useful if you know the
+    name of the C type but not the name of the Scheme type: in that case, you
+    can do <shell|git grep -F GNUNET_MessageHeader> in a git checkout of the
+    source code of Scheme-GNUnet to discover that Scheme-GNUnet's name for
+    <cpp|GNUNET_MessageHeader> is <scm|/:message-header>.
+  </description>
+
+  <todo|TODO: it would be nice to use the properties and documentation to
+  automatically create a form of documentation, with some cross-references to
+  the C code>
+
+  <section|Reading and writing>
+
+  The procedures <scm|read%><index|read%>, <scm|set%!><index|set%!>,
+  <scm|sizeof><index|sizeof> and <scm|select><index|select> from <scm|(gnu
+  gnunet netstruct procedural)> or the like-named macros from <scm|(gnu
+  gnunet netstruct syntactic)> can be used for reading and writing network
+  structures.<space|1em>The macros from <scm|syntactic> behave like the
+  procedures from <scm|procedural> with some optimisations at expansion
+  time.<space|1em>The procedures will be demonstrated with the
+  <scm|/:msg:nse:estimate/example> network structure defined previously.
+
+  First, create a memory slice with <scm|make-slice/read-write> from
+  <scm|(gnu gnunet utils bv-slice)>.<space|1em>The required size can be
+  determinded with <scm|(sizeof /:msg:nse:estimate/example
+  '())>.<space|1em>The role of <scm|'()> will be explained later.
+
+  <\scm-code>
+    (import (gnu gnunet netstruct procedural)
+
+    \ \ \ \ \ \ \ \ (gnu gnunet netstruct syntactic)
+
+    \ \ \ \ \ \ \ \ (gnu gnunet utils bv-slice)
+
+    \ \ \ \ \ \ \ \ (gnu gnunet util struct))
+
+    \;
+
+    (define-type /:msg:nse:estimate/example
+
+    \ \ (structure/packed
+
+    \ \ \ (field (header /:message-header))
+
+    \ \ \ (field (size-estimate ieee-double/big))))
+
+    \;
+
+    (define message
+
+    \ \ (make-slice/read-write (sizeof /:msg:nse:estimate/example '())))
+  </scm-code>
+
+  The fields of <scm|message> can be set with <scm|(set%! netstruct '(field
+  ...) slice value)>.<space|1em>The following code sets all the fields:
+
+  <\scm-code>
+    (set%! /:msg:nse:estimate/example '(header size) message
+
+    \ \ \ \ \ \ \ (sizeof /:msg:nse:estimate/example '()))
+
+    (set%! /:msg:nse:estimate/example '(header type) message 165)
+
+    (set%! /:msg:nse:estimate/example '(size-estimate) message 19.2)
+  </scm-code>
+
+  The size of an individual field can be determined with <scm|(sizeof
+  netstruct '(field ...))>.<space|1em>For example, the following code
+  determines the size of the \<#2018\>size\<#2019\> field in the header:
+
+  <\scm-code>
+    (sizeof /:msg:nse:estimate/example '(header size)) ; 12
+  </scm-code>
+
+  The fields can also be read:
+
+  <\scm-code>
+    (read% /:msg:nse:estimate/example '(header size) message) ; 12
+
+    (read% /:msg:nse:estimate/example '(header type) message) ; 165
+
+    (read% /:msg:nse:estimate/example '(size-estimate) message) ; 19.2
+  </scm-code>
+
+  <section|Primitive types>
+
+  There are a number of pre-defined types.<space|1em>First, there is
+  <scm|u8>, a single octet that is interpreted as an integer in the closed
+  range <math|<around*|[|0,255|]>>.<space|1em>There are also types
+  <scm|uN/endian> for <math|N\<in\><around*|{|16,32,64|}>> and
+  <math|endian\<in\><around*|{|little,big|}>>, which interprets <math|N/8>
+  octets as integers in the closed range 
<math|<around*|[|0,2<rsup|N>-1|]>>.<space|1em>The
+  types <scm|ieee-double/big> and <scm|ieee-double/little> are 8 octets long
+  and represent floating-point numbers in IEEE 754 format
+  (\<#2018\>binary64\<#2019\>).
+
+  <section|Packing>
+
+  In contrast to C structures, Scheme-GNUnet network structures are always
+  packed \V there are no \<#2018\>gaps\<#2019\> between fields.
+</body>
+
+<\initial>
+  <\collection>
+    <associate|page-medium|paper>
+    <associate|save-aux|false>
+  </collection>
+</initial>
\ No newline at end of file
diff --git a/doc/scheme-gnunet.tm b/doc/scheme-gnunet.tm
index e7b9570..0f73fd1 100644
--- a/doc/scheme-gnunet.tm
+++ b/doc/scheme-gnunet.tm
@@ -202,141 +202,7 @@
 
   <chapter|Installation and contributing guide>
 
-  <section|Building from source>
-
-  The latest \<#2018\>official\<#2019\> development version of scheme-GNUnet
-  can be found at 
<hlink|https://git.gnunet.org/gnunet-scheme.git/|https://git.gnunet.org/gnunet-scheme.git/>.
-  It can be downloaded with <hlink|git|https://en.wikipedia.org/wiki/Git>.
-  The following software needs to be installed first:
-
-  <\itemize>
-    <item>The Autotools 
(<hlink|autoconf|https://www.gnu.org/software/autoconf/>
-    and <hlink|automake|https://www.gnu.org/software/automake/>)
-
-    <item><hlink|GNU Guile|https://www.gnu.org/software/guile/> (at least
-    version 3), with the patch from 
<slink|https://debbugs.gnu.org/cgi/bugreport.cgi?bug=49623>
-    applied
-
-    <item><hlink|Purely Functional Data Structures in Scheme
-    (pfds)|https://github.com/ijp/pfds/>
-
-    <item><hlink|(Guile) Fibers|https://github.com/wingo/fibers/>, with the
-    <slink|https://github.com/wingo/fibers/pull/50> patch
-
-    
<item><hlink|Guile-QuickCheck|https://ngyro.com/software/guile-quickcheck.html>
-
-    <item><hlink|Guile-Gcrypt|https://notabug.org/cwebber/guile-gcrypt>
-  </itemize>
-
-  Users of <hlink|GNU Guix|https://guix.gnu.org><index|Guix> can run
-  <shell|guix shell -D gnunet-scheme> in the checkout to create an
-  environment where these dependencies are all
-  present.<space|1em>Scheme-GNUnet uses the standard GNU build system, so to
-  build Scheme-Gnunet, you only need to run
-
-  <\shell-code>
-    autoreconf -vif
-
-    ./configure
-
-    make
-
-    make check
-  </shell-code>
-
-  After building, the documentation is available at
-  <verbatim|doc/scheme-gnunet.pdf> and <verbatim|doc/scheme-gnunet.html> in
-  PDF and HTML formats.<space|1em>To get started, you can run the example
-  mini-application at <verbatim|examples/nse-web.scm> and point your browser
-  at <slink|http://localhost:8089>:
-
-  <\shell-code>
-    $ guile -L . -C . -l examples/nse-web.scm
-  </shell-code>
-
-  <subsection|Authenticating new source code><index|authentication>
-
-  When GNU Guix is present, after pulling the latest Scheme-GNUnet commit,
-  the following command can be run to verify it is authentic:
-
-  <\shell-code>
-    guix git authenticate 088ea8b27b95143584cbc36202c5a02dfe95796c "C1F3 3EE2
-    0C52 8FDB 7DD7 \ 011F 49E3 EE22 1917 25EE"
-  </shell-code>
-
-  If it isn't authentic, an error message such as the following will be
-  written:
-
-  <\shell-code>
-    Authenticating commits 54a74dc to 431f336 (1 new commits)...
-
-    [#########################################################]
-
-    guix git: error: commit 431f336edd51e1f0fe059a6f6f2d4c3e9267b7bc not
-    signed by an authorized key: C1F3 3EE2 0C52 8FDB 7DD7 \ 011F 49E3 EE22
-    1917 25EE
-  </shell-code>
-
-  <section|Writing tests>
-
-  <index|tests>\<#2018\><hlink|How SQLite Is
-  Tested|https://sqlite.org/testing.html>\<#2019\> is a recommended
-  read.<space|1em>Scheme-GNUnet isn't that well-tested but still aims for
-  being free of bugs and having many tests to prevents bugs from being
-  introduced.<space|1em>When adding new code, consider writing test
-  cases.<space|1em>Some things that can be tested and few methods for testing
-  things:
-
-  <\itemize>
-    <item>Run mutation tests.<space|1em>That is, replace in the source code
-    <scm|\<less\>> with <scm|\<less\>=>, <scm|0> with <scm|1>, a variable
-    reference <scm|i> with a variable reference <scm|j>, swap destination and
-    source arguments <text-dots> and verify whether the tests detect these
-    little mutations.
-
-    <item>Be exhaustive.<space|1em>If a procedure handles both foos and bars,
-    write test cases that pass the procedure a foo and test cases that pass
-    the procedure a bar.<space|1em>Sometimes Guile-QuickCheck can help with
-    generating many test cases if the input has a regular structure yet many
-    edge cases, see e.g. <verbatim|tests/cmsg.scm>.
-
-    <item>Verify exception mechanisms!<space|1em>If a procedure is expected
-    to handle I/O errors, simulate I/O errors and end-of-files in all the
-    wrong places.<space|1em>If the procedure can raise exceptions, make sure
-    these exceptions are raised when necessary.
-  </itemize>
-
-  Tests are added in the directory <scm|tests> and to the variable
-  <verbatim|SCM_TESTS> in <verbatim|Makefile.am> and use <scm|srfi
-  :64>.<space|1em>To run the test suite, run <verbatim|make check>.
-
-  <section|Contact>
-
-  Scheme-GNUnet is currently maintained on NotABug:
-  <slink|https://notabug.org/maximed/scheme-gnunet/>.<space|1em>Issues and
-  pull requests can be reported and submitted here.<space|1em>Alternatively,
-  for discussion about developing Scheme-GNUnet, you can send mails to
-  <hlink|gnunet-devel@gnu.org|mailto:gnunet-devel@gnu.org> and for help about
-  how to use Scheme-GNUnet, you can contact
-  <hlink|help-gnunet@gnu.org|mailto:help-gnunet@gnu.org>.<space|1em>These are
-  public mailing lists, so don't send anything there you wouldn't mind the
-  whole world to know.
-
-  For security-sensitive issues, you can send a mail directly to the
-  maintainer, <hlink|Maxime Devos 
\<less\>maximedevos@telenet.be\<gtr\>|mailto:maximedevos@telenet.be>,
-  optionally encrypted and signed with a GnuPG-compatible
-  system.<space|1em>The maintainer's key fingerprint is C1F3 3EE2 0C52 8FDB
-  7DD7 011F 49E3 EE22 1917 25EE and a copy of the key can be downloaded from
-  <slink|https://notabug.org/maximed/things/raw/master/Maxime_Devos.pub>.
-
-  <section|License>
-
-  The code of Scheme-GNUnet is available under the Affero General Public
-  License (AGPL), version 3 or later; see individual source files for
-  details.<space|1em>The documentaton is available under the GNU Free
-  Documentation License, see the start of this manual and the likewise-named
-  appendix for details.<space|1em>The AGPL has some unusual conditions w.r.t.
-  applications interacting with the network, please read it carefully.
+  <include|contributing.tm>
 
   <chapter|Application guide>
 
@@ -364,1014 +230,23 @@
 
   <chapter|Configuration>
 
-  There are a number of modules for accessing GNUnet
-  configurations<index|configuration>.<space|1em>Firstly, there is <scm|(gnu
-  gnunet config db)><index|(gnu gnunet config db)>, which is the module
-  library code would typically use.<space|1em>For testing, one can create an
-  empty configuration with the procedure 
<scm|hash-\<gtr\>configuration><index|hash-\<gtr\>configuration>
-  from that module and <scm|make-hashtable> from <scm|(rnrs hashtables)>,
-  using <scm|hash-key><index|hash-key> as hash function and
-  <scm|key=?><index|key=?> as comparison function:
-
-  <\scm-code>
-    (import (gnu gnunet config db)
-
-    \ \ \ \ \ \ \ \ (gnu gnunet config value-parser)
-
-    \ \ \ \ \ \ \ \ (rnrs hashtables))
-
-    (define config (hash-\<gtr\>configuration (make-hashtable hash-key
-    key=?))
-  </scm-code>
-
-  The resulting configuration <scm|config> is initially empty, so set some
-  <with|font-shape|italic|keys> in the <with|font-shape|italic|section>
-  <verbatim|nse>, to configure the network-size estimation service:
-
-  <\scm-code>
-    (set-value! identity config "nse" "UNIXPATH"
-    "/tmp/nse.sock")<index|set-value!>
-
-    (set-value! number-\<gtr\>string config "cadet" "MAX_ROUTES" 5000)
-
-    ;; TODO: IP address, time durations, booleans, ...
-  </scm-code>
-
-  Now read these values back:
-
-  <\scm-code>
-    (read-value value-\<gtr\>file-name config "nse"
-    "UNIXPATH")<index|read-value>
-
-    ;; -\<gtr\> /tmp/nse.sock
-
-    (read-value value-\<gtr\>natural config "cadet" "MAX_ROUTES")
-
-    ;; -\<gtr\> 5000
-  </scm-code>
-
-  What if the configuration doesn't have a value for the specified section
-  and key?<space|1em>Then an 
<scm|&undefined-key-error><index|&undefined-key-error>
-  results:
-
-  <\scm-code>
-    (read-value value-\<gtr\>natural config "kated" "MAX_ROUTES")
-
-    ;; -\<gtr\>
-
-    ;; ice-9/boot-9.scm:1685:16: In procedure raise-exception:
-
-    ;; ERROR:
-
-    ;; \ \ 1. &undefined-key-error:
-
-    ;; \ \ \ \ \ \ section: "kated"
-
-    ;; \ \ \ \ \ \ key: "MAX_ROUTES"
-  </scm-code>
-
-  <section|Locating configuration files>
-
-  There are two \U possibly non-existent \U configuration files: the
-  <with|font-shape|italic|user> configuration<subindex|configuration|user>
-  and the <with|font-shape|italic|system>
-  configuration<subindex|configuration|system>.<space|1em>The
-  <with|font-shape|italic|system> configuration typically contains the paths
-  for services like NSE, CORE, <text-dots><space|1em>A user may choose not to
-  use the services by the system and instead use their own.<space|1em>To do
-  so, the user needs to override the paths in the
-  <with|font-shape|italic|user> configuration.<space|1em><todo|defaults?> The
-  module <scm|(gnu gnunet config fs)><index|(gnu gnunet config fs)> is
-  responsible for determining the location of the configuration files to load
-  and actually load configuration files.<space|1em>For determining the
-  location of the configuration files, the procedures
-  <scm|locate-user-configuration> and <scm|locate-system-configuration> can
-  be used.
-
-  <\warning>
-    The C implementation's mechanism for user-system separation seems to work
-    differently.
-  </warning>
-
-  <\explain>
-    <scm|(locate-user-configuration 
<scm|#:getenv=getenv>)><index|locate-user-configuration>
-  <|explain>
-    This procedure determines the location of the user configuration file, as
-    a string, or <scm|#false> if it could not be determined.<space|1em>If the
-    location of the user configuration file is known, but the file does not
-    exist, it is returned anyway, as a string.
-
-    If the environment variable <shell|XDG_CONFIG_HOME> is set, the location
-    of the file <verbatim|gnunet.conf> in the directory
-    <shell|$XDG_CONFIG_HOME> is returned.<space|1em>If the environment
-    variable is not set, the location of the file at
-    <verbatim|.config/gnunet.conf><index|~/.config/gnunet.conf> in the home
-    directory specified by the environment variable <verbatim|HOME> is
-    returned, if that environment variable exists.<space|1em>If both are
-    unset, <scm|#false> is returned.
-
-    The values of environment variables is determined with the procedure
-    <scm|getenv>.
-  </explain>
-
-  <\explain>
-    <scm|(locate-system-configuration)><index|locate-system-configuration>
-  <|explain>
-    This procedure determines the location of the system configuration file,
-    as a string.
-
-    Currently, this is always 
<verbatim|/etc/gnunet.conf><index|/etc/gnunet.conf>.
-  </explain>
-
-  <section|Loading configuration files>
-
-  Once the location of the configuration file is known, the file can be
-  opened with the Scheme procedure <scm|open-input-file>, which returns an
-  input port.<space|1em>Then the procedure <scm|load-configuration/port!> can
-  be used to determine all section-key-values triples in the configuration.
-
-  <\explain>
-    <scm|(load-configuration/port! <var|set-value!>
-    <var|port>)><index|load-configuration/port!>
-  <|explain>
-    Load the configuration from the input port <var|port>.
-
-    For each variable, call <var|set-value!> with the section name, variable
-    name and a vector of the form <scm|#(line line-number value)>, where
-    <var|value> a list of expansible objects.
-
-    <todo|document expansible objects><todo|error reporting>
-  </explain>
-
-  A variable assignment<index|variable assignment> <verbatim|[section]
-  key=value${var}> can refer to variables defined in the <verbatim|PATHS>
-  section and variables from the environment.<space|1em>The previously
-  described procedure <scm|load-configuration/port!> will <em|not> expand
-  such assignements. \ To expand variable assignments, use the procedure
-  <scm|make-expanded-configuration> instead.
-
-  <\explain>
-    <scm|(make-expanded-configuration <var|load!>
-    #:getenv=<var|getenv>)><index|make-expanded-configuration>
-  <|explain>
-    Make a configuration object.<space|1em>To populate the configuration, all
-    the procedure <var|load!> with a <scm|set-value!> procedure as expected
-    by <scm|load-configuration/port!>.<space|1em>The values from
-    <scm|set-value!> are added to the confoiguration and every variable is
-    expanded.
-  </explain>
-
-  To automatically load the defaults, the system configuration and the user
-  configuration, use the thunk <scm|load-configuration>:
-
-  <\explain>
-    <scm|(load-configuration #:getenv=<var|getenv>
-    #:files=<text-dots>)><index|load-configuration>
-  </explain|Load the defaults, the system configuration and the user
-  configuration and return the resulting configuration object.<space|1em>The
-  list of files to load can be overriden by setting the undocumented
-  <var|files> keyword argument.>
-
-  Applications (whether graphical or textual) are recommended to use
-  <scm|load-configuration> by default, as it largely just works.
+  <include|configuration.tm>
 
   <chapter|Manipulation of network structures>
 
-  <index|network structure><index|netstruct>The modules <scm|(gnu gnunet
-  netstruct procedural)> and <scm|(gnu gnunet netstruct syntactic)> can be
-  used for formatting messages to be sent over the network or to a
-  service.<space|1em>The macros <scm|define-type><index|define-type> and
-  <scm|structure/packed><index|structure/packed> can be used to define new
-  structures, like this:
-
-  <\scm-code>
-    (define-type /:msg:nse:estimate/example
-
-    \ \ (structure/packed
-
-    \ \ \ (properties '((message-symbol msg:nse:estimate)))
-
-    \ \ \ (synopsis "Network size estimate")
-
-    \ \ \ (documentation "Some explanation")
-
-    \ \ \ (field (header /:message-header))
-
-    \ \ \ (field (size-estimate ieee-double/big)
-
-    \ \ \ \ \ \ \ \ \ \ (synopsis "Timestamp for when the estimate was
-    made"))))
-  </scm-code>
-
-  This example is taken from the <scm|(gnu gnunet nse struct)> module and
-  oversimplified.<space|1em>All its components will gradually
-  explained.<space|1em>First, what actually is a network
-  structure?<space|1em>This question is ambigious, because \<#2018\>network
-  structure\<#2019\> can refer to either the <with|font-shape|italic|value>
-  or the <with|font-shape|italic|type>.<space|1em>The
-  <with|font-shape|italic|value> is a sequence of octets, i.e., a sequence of
-  numbers in the closed range 0\U255.<space|1em>The
-  <with|font-shape|italic|type> describes how the
-  <with|font-shape|italic|value> is structured.
-
-  As an example, consider figure <reference|networkstructex>.<space|1em>There,
-  the value is <scm|0 12 1 65 64 51 238 123 71 27 58 149> and the type is
-  <scm|/:msg:nse:estimate/example>.
-
-  <big-figure|<tree|<scm|/:msg:nse:estimate/example>|<tree|<scm|header>
-  <scm|/:message-header>|<tree|<scm|size> <scm|u16/big>|0
-  12>|<tree|<scm|type> <scm|u16/big>|1 65>>|<tree|<scm|size-estimate>
-  <scm|ieee-double/big>|64 51 238 123 71 27 58 149>>|A network structure,
-  both <with|font-shape|italic|value> and
-  <with|font-shape|italic|type>.<label|networkstructex>>
-
-  This value has a <with|font-shape|italic|header> with a
-  <with|font-shape|italic|size> \<#2018\>0 0 0 12\<#2019\> of type
-  <scm|u32/big>, so the <with|font-shape|italic|size> is 12.<space|1em>The
-  <with|font-shape|italic|header> also has a <with|font-shape|italic|type>
-  \<#2018\>0 0 1 65\<#2019\> of type <scm|u32/big>, so the type is
-  <math|256\<times\>1+65=321>.<space|1em>The value also has a
-  <with|font-shape|italic|size estimate> of type
-  <scm|ieee-double/big>.<space|1em>The octets <scm|64 51 238 123 71 27 58
-  149>, \ interpreted as an IEEE double, form the number
-  <math|19.93\<ldots\>>.
-
-  <section|Documentation>
-
-  A network structure can optionally have embedded
-  documentation.<space|1em>More specifically, network structures can
-  optionally have the <with|font-shape|italic|synopsis><index|synopsis>,
-  <with|font-shape|italic|documentation><index|documentation> and
-  <with|font-shape|italic|properties><index|properties> set.<space|1em>The
-  <with|font-shape|italic|synopsis> is a short description of what the
-  network structure represents, typically a one-liner.<space|1em>The
-  <with|font-shape|italic|documentation> can be more detailed, explaining how
-  the structure works, can be used, is used and should be used.<space|1em>The
-  <with|font-shape|italic|properties> form a free-formed association list.
-
-  The synopsis, documentation and properties can be set on structured created
-  with <scm|structure/packed> and individual fields and can be accessed with
-  the procedures <scm|documentation>, <scm|synopsis> and <scm|properties>.
-
-  The following properties are defined in Scheme-GNUnet:
-
-  <\description>
-    <\item*>
-      <\code>
-        message-symbol
-      </code>
-    </item*>
-
-    <index|message-symbol>For <with|font-shape|italic|message structures>,
-    this is a list of the names of the <with|font-shape|italic|message types>
-    (see <reference|sec:message type> Message type database) this structure
-    can be used for \U most of the time, there's only a single such message
-    type, but sometimes a single structure can be used for multiple message
-    types.
-
-    <item*|c-type>
-
-    <label|c-type>The value is the name of the equivalent type in the C
-    implementation, if any, as a symbol. This can be useful if you know the
-    name of the C type but not the name of the Scheme type: in that case, you
-    can do <shell|git grep -F GNUNET_MessageHeader> in a git checkout of the
-    source code of Scheme-GNUnet to discover that Scheme-GNUnet's name for
-    <cpp|GNUNET_MessageHeader> is <scm|/:message-header>.
-  </description>
-
-  <todo|TODO: it would be nice to use the properties and documentation to
-  automatically create a form of documentation, with some cross-references to
-  the C code>
-
-  <section|Reading and writing>
-
-  The procedures <scm|read%><index|read%>, <scm|set%!><index|set%!>,
-  <scm|sizeof><index|sizeof> and <scm|select><index|select> from <scm|(gnu
-  gnunet netstruct procedural)> or the like-named macros from <scm|(gnu
-  gnunet netstruct syntactic)> can be used for reading and writing network
-  structures.<space|1em>The macros from <scm|syntactic> behave like the
-  procedures from <scm|procedural> with some optimisations at expansion
-  time.<space|1em>The procedures will be demonstrated with the
-  <scm|/:msg:nse:estimate/example> network structure defined previously.
-
-  First, create a memory slice with <scm|make-slice/read-write> from
-  <scm|(gnu gnunet utils bv-slice)>.<space|1em>The required size can be
-  determinded with <scm|(sizeof /:msg:nse:estimate/example
-  '())>.<space|1em>The role of <scm|'()> will be explained later.
-
-  <\scm-code>
-    (import (gnu gnunet netstruct procedural)
-
-    \ \ \ \ \ \ \ \ (gnu gnunet netstruct syntactic)
-
-    \ \ \ \ \ \ \ \ (gnu gnunet utils bv-slice)
-
-    \ \ \ \ \ \ \ \ (gnu gnunet util struct))
-
-    \;
-
-    (define-type /:msg:nse:estimate/example
-
-    \ \ (structure/packed
-
-    \ \ \ (field (header /:message-header))
-
-    \ \ \ (field (size-estimate ieee-double/big))))
-
-    \;
-
-    (define message
-
-    \ \ (make-slice/read-write (sizeof /:msg:nse:estimate/example '())))
-  </scm-code>
-
-  The fields of <scm|message> can be set with <scm|(set%! netstruct '(field
-  ...) slice value)>.<space|1em>The following code sets all the fields:
-
-  <\scm-code>
-    (set%! /:msg:nse:estimate/example '(header size) message
-
-    \ \ \ \ \ \ \ (sizeof /:msg:nse:estimate/example '()))
-
-    (set%! /:msg:nse:estimate/example '(header type) message 165)
-
-    (set%! /:msg:nse:estimate/example '(size-estimate) message 19.2)
-  </scm-code>
-
-  The size of an individual field can be determined with <scm|(sizeof
-  netstruct '(field ...))>.<space|1em>For example, the following code
-  determines the size of the \<#2018\>size\<#2019\> field in the header:
-
-  <\scm-code>
-    (sizeof /:msg:nse:estimate/example '(header size)) ; 12
-  </scm-code>
-
-  The fields can also be read:
-
-  <\scm-code>
-    (read% /:msg:nse:estimate/example '(header size) message) ; 12
-
-    (read% /:msg:nse:estimate/example '(header type) message) ; 165
-
-    (read% /:msg:nse:estimate/example '(size-estimate) message) ; 19.2
-  </scm-code>
-
-  <section|Primitive types>
-
-  There are a number of pre-defined types.<space|1em>First, there is
-  <scm|u8>, a single octet that is interpreted as an integer in the closed
-  range <math|<around*|[|0,255|]>>.<space|1em>There are also types
-  <scm|uN/endian> for <math|N\<in\><around*|{|16,32,64|}>> and
-  <math|endian\<in\><around*|{|little,big|}>>, which interprets <math|N/8>
-  octets as integers in the closed range 
<math|<around*|[|0,2<rsup|N>-1|]>>.<space|1em>The
-  types <scm|ieee-double/big> and <scm|ieee-double/little> are 8 octets long
-  and represent floating-point numbers in IEEE 754 format
-  (\<#2018\>binary64\<#2019\>).
-
-  <section|Packing>
-
-  In contrast to C structures, Scheme-GNUnet network structures are always
-  packed \V there are no \<#2018\>gaps\<#2019\> between fields.
+  <include|network-structures.tm>
 
   <chapter|Communication with services>
 
-  To connect with a GNUnet service<index|services> \V this applies to both
-  the C and Scheme implementation, the GNUnet service must bind a local
-  domain socket<\footnote>
-    The C implementation supports Internet sockets as well.
-  </footnote> somewhere on the file system and the client (possibly another
-  service) must connect to it.<space|1em>Connections to a service can be made
-  with the <scm|connect/fibers><index|connect/fibers> procedure from
-  <scm|(gnu gnunet mq-impl stream)><index|(gnu gnunet mq-impl stream)>, like
-  this:
-
-  <\scm-code>
-    (define mq (connect/fibers config "nse" handlers error-handler))
-  </scm-code>
-
-  <section|Asynchronuously connecting><index|connecting to services>
-
-  This is an asynchronuous operation: it will \<#2018\>complete\<#2019\>
-  immediately and the connection will actually be formed in the
-  background.<space|1em>When the connection has actually be formed, the
-  <scm|error-handler><index|error-handler> is called with the symbol
-  <scm|connection:connected><index|connection:connected>.<space|1em>To
-  demonstrate, the following code asynchronuously connects to the NSE
-  service, and prints the text <scm|"connected!"> when the connection has
-  actually been formed.
-
-  <\scm-code>
-    ;; XXX test this, explain 'config' ...
-
-    (define (error-handler error . args)
-
-    \ \ (case error
-
-    \ \ \ \ ((connection:connected)
-
-    \ \ \ \ \ (format #t "connected!~%"))
-
-    \ \ \ \ (else (format #t "unknown error: ~a ~a~%" error args))))
-
-    \;
-
-    (define mq
-
-    \ \ (connect/fibers config "nse" (message-handlers) error-handler))
-  </scm-code>
-
-  <section|Message handler>
-
-  <index|message handler>When a message is received by the message queue, the
-  corresponding message handler is invoked.<space|1em>Message handlers can be
-  constructed with the <scm|message-handler><index|message-handler> macro and
-  the <scm|make-message-handler><index|make-message-handler> procedure from
-  <scm|(gnu gnunet mq handler)>, as follows:
-
-  <\scm-code>
-    (import (gnu gnunet mq handler)
-
-    \ \ \ \ \ \ \ \ (gnu extractor enum)
-
-    \ \ \ \ \ \ \ \ (gnu gnunet message protocols)
-
-    \ \ \ \ \ \ \ \ (gnu gnunet util struct)
-
-    \ \ \ \ \ \ \ \ (gnu gnunet utils bv-slice)
-
-    \ \ \ \ \ \ \ \ (gnu gnunet netstruct syntactic))
-
-    \;
-
-    (define handler/syntactic
-
-    \ \ (message-handler
-
-    \ \ \ (type (symbol-value message-type msg:util:dummy))
-
-    \ \ \ ((interpose code) code)
-
-    \ \ \ ((well-formed? slice)
-
-    \ \ \ \ (= (slice-length slice)
-
-    \ \ \ \ \ \ \ (sizeof /:message-header '())))
-
-    \ \ \ ((handle! slice)
-
-    \ \ \ \ (pk 'message: slice))))
-
-    \;
-
-    (define handler/procedural
-
-    \ \ (make-message-handler
-
-    \ \ \ (symbol-value message-type msg:util:dummy)
-
-    \ \ \ (lambda (thunk) (thunk))
-
-    \ \ \ (lambda (slice)
-
-    \ \ \ \ \ (= (slice-length slice)
-
-    \ \ \ \ \ \ \ \ (sizeof /:message-header '())))
-
-    \ \ \ (lambda (slice)
-
-    \ \ \ \ \ (pk 'message: slice))))
-  </scm-code>
-
-  As illustrated in the example code above, a message handler has four
-  components: the <with|font-shape|italic|type> of message<subindex|message
-  type|of handler> it handles, an 
<with|font-shape|italic|interposer><index|interposer>
-  which will be explained later, the 
<with|font-shape|italic|verifier><index|verifier>
-  deciding if a message is well-formed and the
-  <with|font-shape|italic|handler procedure><index|handler procedure>.
-
-  The verifier is passed a bytevector slice with the message and should
-  return <scm|#true> if the message is well-formed and <scm|#false> if it
-  isn't.<space|1em>It may assume that the length of the slice corresponds to
-  the length <em|in> the message header and is at least the length <em|of>
-  the message header and that the type in the message header corresponds to
-  the type of the message handler.<space|1em>Messages will only be passed to
-  the handler procedue if the verifiers returns <scm|#true>.
-
-  The handler procedure is passed a bytevector slice with the message, but
-  only if the verifier considers it well-formed.<space|1em>The handler
-  procedure and verifier are run from the
-  <with|font-shape|italic|interposer>.<space|1em>The interposer is passed a
-  thunk to execute and may e.g. install exception handlers and parameterise
-  parameters.<space|1em>It can change the current input, output and error
-  ports for example.
-
-  <todo|document the message type database, various procedures>
-
-  <section|Message type database><label|sec:message type><subindex|message
-  type|database>
-
-  The module <scm|(gnu gnunet message protocols)><index|(gnu gnunet message
-  protocols)> has a mapping of symbolic names of every message type known to
-  scheme-GNUnet to their numeric value.<space|1em>To use it, the macro
-  <scm|symbol-value><index|symbol-value> from <scm|(gnu extractor
-  enum)><index|(gnu extractor enum)> is required and possibly
-  <scm|value-\<gtr\>index><index|value-\<gtr\>index> as well.<space|1em>To
-  determine the numeric value of the message type <scm|msg:nse:estimate>, one
-  would write:
-
-  <\scm-code>
-    (define numeric-type
-
-    \ \ (value-\<gtr\>index (symbol-value message-type msg:nse:estimate)))
-  </scm-code>
-
-  <todo|other various enum procedures for introspection, documentation,
-  <text-dots>?>
-
-  <todo|how to define new message types>
-
-  <section|Error handler><index|error handler>
-
-  The message queue implementation usually just sends and receives messages,
-  but some exceptional situations cannot be communicated with
-  <scm|send-message!> or <scm|inject-message!>.<space|1em>For those, there is
-  the <scm|inject-error!><index|inject-error!> procedure.<space|1em>This
-  variadic procedure accepts a message queue to inject the error into, a
-  <with|font-shape|italic|key><index|key> (usually a symbol) describing the
-  exceptional situation and rest arguments.<space|1em>It calls the
-  <with|font-shape|italic|error handler> of the message queue with the key
-  and rest arguments.<space|1em>The following errors can currently be
-  reported by the built-in message queue implementations:
-
-  <\explain>
-    <scm|connection:connected><index|connection:connected>
-  <|explain>
-    The connection to the server has been established.
-  </explain>
-
-  <\explain>
-    <scm|connection:interrupted><index|connection:interrupted>
-  </explain|The message queue has been closed before the connection to the
-  server could be established.>
-
-  <\explain>
-    <scm|input:regular-end-of-file><index|input:regular-end-of-file>
-  <|explain>
-    The connection has been closed by the server.
-
-    For people wondering about what happens if a connection becomes
-    half-duplex: GNUnet does not have a notion of half-duplex message
-    streams.<space|1em>If it is detected the underlying stream became
-    half-duplex anyways, it will be treated as closed by scheme-GNUnet,
-    resulting in this error.<space|1em>However, note that currently broken
-    pipes cannot be reliably detected.
-  </explain>
-
-  <\explain>
-    <scm|input:premature-end-of-file><index|input:premature-end-of-file>
-  </explain|The connection was closed by the server while a message was still
-  being read.<space|1em>This can happen if the server was stopped while it
-  was still sending the rest of the message.>
-
-  <\explain>
-    <scm|input:overly-small> <var|type> <var|size><index|input:overly-small>
-  </explain|The message size in the header was smaller than the minimal
-  message size.<space|1em>Sometimes, but not always, the message type
-  <var|type> and message size <var|size> are available (as exact
-  naturals).<space|1em>When they are not available, <var|type> and <var|size>
-  are <scm|#false> instead.<space|1em>This can only happen if the server or
-  connection to the server is buggy.>
-
-  <\explain>
-    <scm|logic:no-handler> <var|type> . <var|rest><index|logic:no-handler>
-  <|explain>
-    The received message of type <var|type> (as an integer) does not have a
-    corresponding message handler.<space|1em><var|rest> is currently
-    unspecified.
-  </explain>
-
-  <\explain>
-    <scm|logic:ill-formed> <var|type> . <var|rest><index|logic:ill-formed>
-  </explain|The received message of type (as an integer) is ill-formed
-  according to the message handler.<space|1em><var|rest> is currently
-  unspecified.>
-
-  Consider automatically reconnecting after
-  <scm|<scm|input:regular-end-of-file>> and
-  <scm|<scm|input:premature-end-of-file>>, to allow the server to restart
-  without having to manually restart every individual
-  application.<space|1em>To report errors, see the section
-  <reference|sec:error reporting> Error reporting.
-
-  <section|Ordering of injected errors and messages and sent messages>
-
-  This section describes how injected errors and messages and sent messages
-  are ordered with respect to each other in the default message queue
-  implementation.<space|1em>Messages are handled or corresponding
-  <scm|logic:no-handler> or <scm|logic:ill-formed> errors are injected in the
-  order that the messages are received.<space|1em>Before messages are read,
-  <scm|connection:connected> is injected.<space|1em>This error is injected at
-  most once.
-
-  <em|Soon> after all messages are read (and therefore
-  <with|font-shape|italic|soon> after all handled messages or corresponding
-  errors), the error <scm|input:regular-end-of-file>,
-  <scm|input:overly-small> or <scm|input:premature-end-of-file> is
-  injected.<space|1em>Only one of those errors can be injected for the entire
-  lifetime of the message queue.
-
-  Be aware that <em|soon> is not <em|immediate> here!<space|1em>For example,
-  it is possible for a message to be received, the port closed, a message
-  queued for sending, the closing of the port being detected by the write
-  fiber, <scm|input:regular-end-of-file> being injected from the write fiber
-  and the read fiber handling the received message, and the read fiber
-  exiting because the port is closed, in that order.
-
-  Messages are sent (and received on the other side) in the order they were
-  enqueued for sending.<space|1em>Likewise, the notify-sent callback of
-  enqueued messages are called in order.<space|1em>If the notify-sent
-  callback is called, it is before the message is received by the other
-  side.<space|1em>The message and its notify-sent callback are only received
-  by the other side and called after the message has been injected and
-  <scm|connection:connected> has been injected.<space|1em>It is possible for
-  the notify-sent callback to be called without the message being received by
-  the other side, e.g. if the port was closed during the notify-sent
-  callback.
-
-  If a message is received by the other side, all previously-sent messages
-  have be received before.<space|1em>If a notify-sent callback is invoked,
-  all notify-sent callbacks of previous messages have been invoked before,
-  except the messages that are eventually cancelled.
-
-  The errors <scm|logic:no-handler> and <scm|logic:ill-formed> are not fatal:
-  later messages can still be read and handled.<space|1em>If
-  <scm|connection:interrupted> is injected, no other errors are ever
-  injected, whether in the past or in the future.<space|1em>This error can
-  only be injected once.
-
-  <todo|I/O errors>
-
-  <todo|envelopes>
-
-  <section|Disconnecting><index|disconnecting>
-
-  A message queue can be closed with the <scm|close-queue!><index|close-queue!>
-  procedure from <scm|(gnu gnunet mq)>.<space|1em>In the default message
-  queue implementation, this asynchronuously closes the port and stops
-  associated fibers.<space|1em>Closing ports when they won't be used anymore
-  is important for limiting resource consumption, especially for servers that
-  can have many connections.<space|1em>Closing message queues is an
-  idempotent operation: closing a message queue twice is the same as closing
-  it once.<space|1em> If a message queue is closed before a connection could
-  be formed, <scm|connection:interrupted><index|connection:interrupted> is
-  injected instead of <scm|connection:connected> and
-  <scm|connection:regular-end-of-file>.
-
-  <section|Error reporting><label|sec:error reporting>
-
-  <index|error reporting>Errors can be reported with the procedure
-  <scm|report-error> from the module <scm|(gnu gnunet mq
-  error-reporting)><index|(gnu gnunet mq error-reporting)>.<space|1em>It can
-  be called as <scm|(report-error key argument ...)>, e.g. <scm|(report-error
-  'logic:no-handler 3)><index|report-error>.<space|1em>By default, it reports
-  the error to the current error port.<space|1em>If this is not desired, the
-  output can be sent to another port by setting the parameter
-  
<scm|textual-error-reporting-port><index|textual-error-reporting-port>.<space|1em>If
-  textual error reporting is not desired, the parameter
-  <scm|error-reporter><index|error-reporter> can be set to a procedure with
-  the same interface as <scm|report-error>.<space|1em>Such a procedure could
-  e.g. open a GUI dialog, sent the message to the system logger or ignore the
-  error.
-
-  Error messages are translated for the current locale.<todo|TODO actually
-  call bindtextdomain>
+  <include|service-communication.tm>
 
   <chapter|Estimation of the size of the network>
 
-  <index|network size estimation><index|NSE>GNUnet has a service that roughly
-  estimates the size of the network \U i.e., the number of
-  peers.<space|1em>The module <scm|(gnu gnunet nse client)><index|(gnu gnunet
-  nse client)> can be used to interact with this service.<space|1em>The
-  connection is made with the procedure <scm|connect><subindex|connect|NSE>,
-  which is accepts a <with|font-shape|italic|configuration> (see
-  <todo|reference>) and some optional keyword arguments.<space|1em>This
-  procedure can be called as <scm|(connect config #:updated updated
-  #:connected connected #:disconnected disconnected)>.<space|1em>It returns a
-  <with|font-shape|italic|NSE server object><index|NSE server
-  object><subindex|server object|NSE>.
-
-  The connection is made asynchronuously; the thunk <var|connected> will be
-  called when the connection has actually been made.<space|1em>Whenever a new
-  estimate becomes available, the (optional) procedure
-  <var|updated><index|update procedure> is called with the new
-  <with|font-shape|italic|estimate><index|estimate
-  object>.<space|1em>Alternatively, the procedure
-  <scm|estimate><index|estimate> can be called on the server object to return
-  the latest available estimate.<space|1em>If the
-  <with|font-shape|italic|server object> doesn't have an estimate yet, that
-  procedure will return <scm|#false> instead of an estimate.
-
-  When the connection is lost, the (optional) thunk <var|disconnected> is
-  called and <scm|(gnu gnunet nse client)> will retry
-  connecting.<space|1em>To close the current connection, if any, and stop
-  reconnecting, the idempotent procedure 
<scm|disconnect!><subindex|disconnect!|NSE>
-  can be called on the server object.
-
-  <todo|input, validation, I/O errors?>
-
-  The estimate object has a number of accessors:
-
-  <\explain>
-    <scm|(estimate:logarithmic-number-peers
-    <var|estimate>)><index|estimate:logarithmic-number-peers>
-  </explain|The base-2 logarithm of the number of peers (estimated), as a
-  positive flonum, possibly zero or infinite>
-
-  <\explain>
-    <scm|(estimate:number-peers <var|estimate>)><index|estimate:number-peeers>
-  </explain|The number of peers (estimated), as a flonum, at least <scm|1.0>
-  and possibly infinite.<space|1em>This is not necessarily an (inexact)
-  <scm|integer?>, as it is only an estimate.>
-
-  <\explain>
-    <scm|(estimate:timestamp estimate)><index|estimate:timestamp>
-  </explain|A timestamp when the estimate was made <todo|something about
-  epoch?>>
-
-  <\explain>
-    <scm|(estimate:standard-deviation 
<var|estimate>)><index|estimate:standard-deviation>
-  <|explain>
-    The estimated standard deviation on the base-2 logarithm of peers,
-    calculated over the last 64 rounds, with the <math|<frac|N|N-1>>
-    correction.<space|1em>This is a positive flonum, possibly zero or
-    infinite, or not-a-number (indicating division of zero by zero).
-
-    If the peer has been connected to the network for a while, the number is
-    expected to be finite and strictly positive.
-  </explain>
-
-  Assuming the network size is stable and the errors on the logarithmic
-  estimate are normally distributed, the procedure
-  <scm|estimate:standard-deviation> can be used to put probablistic error
-  bounds on the number of peers on the network. <todo|example>
+  <include|network-size-estimation.tm>
 
   <chapter|Accessing the DHT>
 
-  GNUnet has a service that maintains a <em|distributed hash
-  table><index|distributed hash table><index|DHT><index|R5N>, mapping keys to
-  values. The module <scm|(gnu gnunet dht client)><index|(gnu gnunet dht
-  client)> can be used to interact with the service. The connection can be
-  made with the procedure <scm|connect>. It returns a <em|DHT server
-  object><index|DHT server object><subindex|server object|DHT>.
-
-  <\explain>
-    <scm|(connect <var|config> <var|#:connected> <var|#:disconnected>
-    <var|#:spawn>)><subindex|connect|DHT>
-  <|explain>
-    Connect to the DHT service, using the configuration <var|config>. The
-    connection is made asynchronuously; the optional thunk <var|connected> is
-    called when the connection has been made. The connection can break; the
-    optional thunk <var|disconnected> is called when it does. If the
-    connection breaks, the client code automatically tries to reconnect, so
-    <var|connected> can be called after <var|disconnected>.
-  </explain>
-
-  <\explain>
-    <scm|(disconnect! <var|server>)><subindex|disconnect!|DHT>
-  <|explain>
-    Asynchronuously disconnect from the DHT service and stop reconnecting,
-    even if not connected. This is an idempotent operation.
-  </explain>
-
-  <section|Data in the DHT>
-
-  To insert data into the DHT, the DHT service needs various information \U
-  the key and the value, but also some other information. Likewise, when the
-  DHT service has found the datum, this information is available as well. A
-  datum in the DHT is represented as a <em|datum object><index|datum object>.
-  The object holding the information required for inserting something in the
-  DHT is called an <em|insertion object><index|insertion object>. Likewise,
-  the information of searching for something in the DHT is in a <em|query
-  object><index|query object>. The result of a query is a <em|search result
-  object><index|search result object>.
-
-  These objects only hold information; creating them does not have any side
-  effects.
-
-  <\explain>
-    <scm|(make-datum <var|type> <var|key> <var|value>
-    <var|#:expiration>)><index|make-datum>
-  <|explain>
-    Make a datum object of block type <var|type> (or its corresponding
-    numeric value), with key <var|key> (a readable <scm|/hashcode:512>
-    bytevector slice), value <var|value> (a readable bytevector slice) and
-    expiring at <var|expiration> (<todo|type, epoch>). The keyword argument
-    <var|expiration> is optional, see <reference|???>.
-
-    The numeric value of the block type can be retrieved with the accessor
-    <scm|datum-type>. The accessors <scm|datum-key><index|datum-key>,
-    <scm|datum-value><index|datum-value> and
-    <scm|datum-expiration><index|datum-expiration> return the key, value and
-    expiration time respectively. It can be tested if an object is a datum
-    object with the predicate <scm|datum?><index|datum?>.
-
-    The length of <var|value> may be at most
-    <scm|%max-datum-value-length><index|%max-datum-value-length>. If this
-    bound is exceeded, an appropriate 
<scm|&overly-large-datum><index|&overly-large-datum>
-    and <scm|&who> condition is raised.
-  </explain>
-
-  <\explain>
-    <scm|(datum-\<gtr\>insertion <var|datum>
-    #:desired-replication-level)><index|datum-\<gtr\>insertion>
-  <|explain>
-    Make an insertion object for inserting the datum <var|datum>, desiring a
-    replication level <var|desired-replication-level> (see
-    <reference|replication levels???>)<todo|various options>.
-
-    The datum and desired replication level can be recovered with the
-    accessors <scm|insertion-\<gtr\>datum><index|insertion-\<gtr\>datum> and
-    
<var|insertion-desired-replication-level><index|insertion-desired-replication-level>.
-    It can be tested if an object is an insertion object with the predicate
-    <scm|insertion?><index|insertion?>.
-  </explain>
-
-  <\explain>
-    <scm|(make-query <var|type> <var|key>
-    #:desired-replication-level)><index|make-query>
-  <|explain>
-    Make a query object for searching for a value of block type <var|type>
-    (or its corresponding numeric value), with key <var|key> (a readable
-    <scm|/hashcode:512> bytevector slice), at desired replication level
-    <scm|desired-replication-level> (see <reference|replication levels???>).
-    <todo|various options, xquery>
-
-    The numeric value of the block type, the key and the desired replication
-    level can be recovered with the accessors
-    <scm|query-type><index|query-type>, <scm|query-key><index|query-key> and
-    
<scm|query-desired-replication-level><index|query-desired-replication-level>.
-    It can be tested if an object is a query object with the predicate
-    <scm|query?><index|query?>.
-  </explain>
-
-  <\explain>
-    <scm|(datum-\<gtr\>search-result <var|datum> #:get-path
-    #:put-path)><index|datum-\<gtr\>search-result>
-  <|explain>
-    Make a search result object for the datum <var|datum>. The datum can be
-    recovered with the accessor 
<scm|search-result-\<gtr\>datum><index|search-result-\<gtr\>datum>.
-    It can be tested if an object is a search result with the predicate
-    <scm|search-result?><index|search-result?>. The optional arguments
-    <var|get-path> and <var|put-path>, when not false, are bytevector slices
-    consisting of a list of 
<scm|/dht:path-element><index|/dht:path-element><index|path
-    element>.
-
-    The <var|get-path><index|get path> , if any, is the path from the storage
-    location to the current peer. Conversely, the <var|put-path><index|put
-    path>, if any, is a path from the peer that inserted the datum into the
-    DHT to the storage location. The <var|get-path> and <var|put-path> can be
-    accessed with <scm|search-result-get-path><index|search-result-get-path>
-    and <scm|search-result-put-path><index|search-result-put-path>
-    respectively.
-
-    When the datum, get path and put path together are too large, a
-    <scm|&overly-large-paths><index|&overly-large-paths> condition is raised.
-    When the bytevector slice length of <var|get-path> or <var|put-path> is
-    not a multiple of the size of a path element, then a
-    <scm|&malformed-path><index|&malformed-path> condition is raised.
-  </explain>
-
-  <section|Accessing data in the DHT>
-
-  To insert a datum into the DHT, the procedure <scm|put!> is used. To find
-  data matching a query, the procedure <scm|start-get!> is
-  used.<index|searching the DHT><index|inserting data into the DHT>
-
-  <\explain>
-    <scm|(start-get! <var|server> <var|query> <var|found>)><index|start-get!>
-  <|explain>
-    Search for data matching <var|query> in the DHT. When a datum is found,
-    call the unary procedure <var|found> on the search result. It is possible
-    to find multiple data matching a query. In that case, <var|found> is
-    called multiple times. Searching happens asynchronuously; to stop the
-    search, a fresh <em|search object><index|search object> for controlling
-    the search is returned.
-
-    The procedure <var|found> is run from the context of <var|server>. As
-    such, if <var|found> blocks, then all operations on <var|server> might
-    block. As such, it is recommended for <var|found> to do as little as
-    possible by itself and instead delegate any work to a separate fiber.
-
-    To avoid expensive copies, the implementation can choose to reuse
-    internal buffers for the slices passed to <var|found>, which could be
-    overwritten after the call to <var|found>. As such, it might be necessary
-    to make a copy of the search result, using <scm|copy-search-result>.
-  </explain>
-
-  <\explain>
-    <scm|(put! <var|server> <var|insertion> <var|#:confirmed>)><index|put!>
-  <|explain>
-    Perform the insertion <var|insertion>. When the datum has been inserted,
-    the optional thunk <var|confirmed> is called. A <em|put object> is
-    returned which can be used to cancel the insertion.
-
-    <todo|TODO: actually call <var|confirmed>>
-  </explain>
-
-  <\explain>
-    <scm|(copy-query <var|old>)><index|copy-query>
-
-    <scm|(copy-datum <var|old>)><index|copy-datum>
-
-    <scm|(copy-insertion <var|old>)><index|copy-insertion>
-
-    <scm|(copy-search-result <var|old>)><index|copy-search-result>
-  <|explain>
-    Make a copy of the object <var|old> (a query, datum, insertion or search
-    result object, depending on the procedure), such that modifications to
-    the slices in <var|old> do not impact the new object.
-  </explain>
-
-  <todo|cancellation>
-
-  <section|Constructing and analysing network messages>
-
-  The DHT client and service communicate by sending <em|messages>. Usually,
-  only the implementation of the client and service need to construct and
-  analyse these messages, but nothing prevents other uses of the procedures
-  in <scm|(gnu gnunet dht network)><index|(gnu gnunet dht network)>, e.g. for
-  learning, in a tool like Wireshark or for tests.
-
-  The <em|analysis> procedures<index|analysis procedures> assume that the
-  message is well-formed and avoid constructing new bytevector slices by
-  taking subslices. The <em|construction> procedures<index|construction
-  procedures> create fresh well-formed read-write bytevector slices.
-
-  <\warning>
-    Possibly the type of <var|options> will change and possibly the options
-    will be moved into the query object and insertion object.
-  </warning>
-
-  <\explain>
-    <scm|(construct-client-get <var|query> <var|unique-id> #:optional
-    (<var|options> 0))><index|construct-client-get>
-  <|explain>
-    Create a new <scm|/:msg:dht:client:get><index|/:msg:dht:client:get>
-    message for the query object <var|query>, with <var|unique-id> as
-    \<#2018\>unique id\<#2019\> and <var|options> as options.
-  </explain>
-
-  <\explain>
-    <scm|(construct-client-put <var|insertion> #:optional (options
-    0))><index|construct-client-put>
-  <|explain>
-    Create a new <scm|/:msg:dht:client:put><index|/:msg:dht:client:put>
-    message for the insertion object <var|insertion> with <var|options> as
-    options.
-  </explain>
-
-  <\explain>
-    <scm|(construct-client-result <var|search-result>
-    <var|unique-id>)><index|construct-client-result>
-  <|explain>
-    Create a new <scm|/:msg:dht:client:result><index|/:msg:dht:client:result>
-    message for the search result object <var|search-result>, with
-    <var|unique-id> as \<#2018\>unique id\<#2019\> .
-  </explain>
-
-  <\explain>
-    <scm|(analyse-client-get <var|message>)><index|analyse-client-get>
-  <|explain>
-    Return the query object, the unique id and the options corresponding to
-    the <scm|/:msg:dht:client:result><index|/:msg:dht:client:result> message
-    <var|message>. Xqueries are currently unsupported.
-  </explain>
-
-  <\explain>
-    <scm|(analyse-client-put <var|message>)><index|analyse-client-put>
-  <|explain>
-    Return the insertion object and options corresponding to the
-    <scm|/:msg:dht:client:put><index|/:msg:dht:client:put> message
-    <var|message>.
-  </explain>
-
-  <\explain>
-    <scm|(analyse-client-result <var|message>)><index|analyse-client-result>
-  <|explain>
-    Return search result object and unique id for the
-    <scm|/:msg:dht:client:result><index|/:msg:dht:client:result> message
-    <var|message>.
-  </explain>
-
-  <todo|monitoring messages>
-
-  <section|How to handle invalid data>
-
-  <todo|todo!>
-
-  <section|Monitoring: spying on what other applications and peers are doing>
-
-  <todo|todo!>
+  <include|distributed-hash-table.tm>
 
   <chapter|Cryptography>
 
@@ -1699,6 +574,7 @@
 <\initial>
   <\collection>
     <associate|page-medium|paper>
+    <associate|project-flag|true>
     <associate|save-aux|false>
   </collection>
 </initial>
\ No newline at end of file
diff --git a/doc/service-communication.tm b/doc/service-communication.tm
new file mode 100644
index 0000000..056be14
--- /dev/null
+++ b/doc/service-communication.tm
@@ -0,0 +1,325 @@
+<TeXmacs|2.1>
+
+<project|scheme-gnunet.tm>
+
+<style|tmmanual>
+
+<\body>
+  To connect with a GNUnet service<index|services> \V this applies to both
+  the C and Scheme implementation, the GNUnet service must bind a local
+  domain socket<\footnote>
+    The C implementation supports Internet sockets as well.
+  </footnote> somewhere on the file system and the client (possibly another
+  service) must connect to it.<space|1em>Connections to a service can be made
+  with the <scm|connect/fibers><index|connect/fibers> procedure from
+  <scm|(gnu gnunet mq-impl stream)><index|(gnu gnunet mq-impl stream)>, like
+  this:
+
+  <\scm-code>
+    (define mq (connect/fibers config "nse" handlers error-handler))
+  </scm-code>
+
+  <section|Asynchronuously connecting><index|connecting to services>
+
+  This is an asynchronuous operation: it will \<#2018\>complete\<#2019\>
+  immediately and the connection will actually be formed in the
+  background.<space|1em>When the connection has actually be formed, the
+  <scm|error-handler><index|error-handler> is called with the symbol
+  <scm|connection:connected><index|connection:connected>.<space|1em>To
+  demonstrate, the following code asynchronuously connects to the NSE
+  service, and prints the text <scm|"connected!"> when the connection has
+  actually been formed.
+
+  <\scm-code>
+    ;; XXX test this, explain 'config' ...
+
+    (define (error-handler error . args)
+
+    \ \ (case error
+
+    \ \ \ \ ((connection:connected)
+
+    \ \ \ \ \ (format #t "connected!~%"))
+
+    \ \ \ \ (else (format #t "unknown error: ~a ~a~%" error args))))
+
+    \;
+
+    (define mq
+
+    \ \ (connect/fibers config "nse" (message-handlers) error-handler))
+  </scm-code>
+
+  <section|Message handler>
+
+  <index|message handler>When a message is received by the message queue, the
+  corresponding message handler is invoked.<space|1em>Message handlers can be
+  constructed with the <scm|message-handler><index|message-handler> macro and
+  the <scm|make-message-handler><index|make-message-handler> procedure from
+  <scm|(gnu gnunet mq handler)>, as follows:
+
+  <\scm-code>
+    (import (gnu gnunet mq handler)
+
+    \ \ \ \ \ \ \ \ (gnu extractor enum)
+
+    \ \ \ \ \ \ \ \ (gnu gnunet message protocols)
+
+    \ \ \ \ \ \ \ \ (gnu gnunet util struct)
+
+    \ \ \ \ \ \ \ \ (gnu gnunet utils bv-slice)
+
+    \ \ \ \ \ \ \ \ (gnu gnunet netstruct syntactic))
+
+    \;
+
+    (define handler/syntactic
+
+    \ \ (message-handler
+
+    \ \ \ (type (symbol-value message-type msg:util:dummy))
+
+    \ \ \ ((interpose code) code)
+
+    \ \ \ ((well-formed? slice)
+
+    \ \ \ \ (= (slice-length slice)
+
+    \ \ \ \ \ \ \ (sizeof /:message-header '())))
+
+    \ \ \ ((handle! slice)
+
+    \ \ \ \ (pk 'message: slice))))
+
+    \;
+
+    (define handler/procedural
+
+    \ \ (make-message-handler
+
+    \ \ \ (symbol-value message-type msg:util:dummy)
+
+    \ \ \ (lambda (thunk) (thunk))
+
+    \ \ \ (lambda (slice)
+
+    \ \ \ \ \ (= (slice-length slice)
+
+    \ \ \ \ \ \ \ \ (sizeof /:message-header '())))
+
+    \ \ \ (lambda (slice)
+
+    \ \ \ \ \ (pk 'message: slice))))
+  </scm-code>
+
+  As illustrated in the example code above, a message handler has four
+  components: the <with|font-shape|italic|type> of message<subindex|message
+  type|of handler> it handles, an 
<with|font-shape|italic|interposer><index|interposer>
+  which will be explained later, the 
<with|font-shape|italic|verifier><index|verifier>
+  deciding if a message is well-formed and the
+  <with|font-shape|italic|handler procedure><index|handler procedure>.
+
+  The verifier is passed a bytevector slice with the message and should
+  return <scm|#true> if the message is well-formed and <scm|#false> if it
+  isn't.<space|1em>It may assume that the length of the slice corresponds to
+  the length <em|in> the message header and is at least the length <em|of>
+  the message header and that the type in the message header corresponds to
+  the type of the message handler.<space|1em>Messages will only be passed to
+  the handler procedue if the verifiers returns <scm|#true>.
+
+  The handler procedure is passed a bytevector slice with the message, but
+  only if the verifier considers it well-formed.<space|1em>The handler
+  procedure and verifier are run from the
+  <with|font-shape|italic|interposer>.<space|1em>The interposer is passed a
+  thunk to execute and may e.g. install exception handlers and parameterise
+  parameters.<space|1em>It can change the current input, output and error
+  ports for example.
+
+  <todo|document the message type database, various procedures>
+
+  <section|Message type database><label|sec:message type><subindex|message
+  type|database>
+
+  The module <scm|(gnu gnunet message protocols)><index|(gnu gnunet message
+  protocols)> has a mapping of symbolic names of every message type known to
+  scheme-GNUnet to their numeric value.<space|1em>To use it, the macro
+  <scm|symbol-value><index|symbol-value> from <scm|(gnu extractor
+  enum)><index|(gnu extractor enum)> is required and possibly
+  <scm|value-\<gtr\>index><index|value-\<gtr\>index> as well.<space|1em>To
+  determine the numeric value of the message type <scm|msg:nse:estimate>, one
+  would write:
+
+  <\scm-code>
+    (define numeric-type
+
+    \ \ (value-\<gtr\>index (symbol-value message-type msg:nse:estimate)))
+  </scm-code>
+
+  <todo|other various enum procedures for introspection, documentation,
+  <text-dots>?>
+
+  <todo|how to define new message types>
+
+  <section|Error handler><index|error handler>
+
+  The message queue implementation usually just sends and receives messages,
+  but some exceptional situations cannot be communicated with
+  <scm|send-message!> or <scm|inject-message!>.<space|1em>For those, there is
+  the <scm|inject-error!><index|inject-error!> procedure.<space|1em>This
+  variadic procedure accepts a message queue to inject the error into, a
+  <with|font-shape|italic|key><index|key> (usually a symbol) describing the
+  exceptional situation and rest arguments.<space|1em>It calls the
+  <with|font-shape|italic|error handler> of the message queue with the key
+  and rest arguments.<space|1em>The following errors can currently be
+  reported by the built-in message queue implementations:
+
+  <\explain>
+    <scm|connection:connected><index|connection:connected>
+  <|explain>
+    The connection to the server has been established.
+  </explain>
+
+  <\explain>
+    <scm|connection:interrupted><index|connection:interrupted>
+  </explain|The message queue has been closed before the connection to the
+  server could be established.>
+
+  <\explain>
+    <scm|input:regular-end-of-file><index|input:regular-end-of-file>
+  <|explain>
+    The connection has been closed by the server.
+
+    For people wondering about what happens if a connection becomes
+    half-duplex: GNUnet does not have a notion of half-duplex message
+    streams.<space|1em>If it is detected the underlying stream became
+    half-duplex anyways, it will be treated as closed by scheme-GNUnet,
+    resulting in this error.<space|1em>However, note that currently broken
+    pipes cannot be reliably detected.
+  </explain>
+
+  <\explain>
+    <scm|input:premature-end-of-file><index|input:premature-end-of-file>
+  </explain|The connection was closed by the server while a message was still
+  being read.<space|1em>This can happen if the server was stopped while it
+  was still sending the rest of the message.>
+
+  <\explain>
+    <scm|input:overly-small> <var|type> <var|size><index|input:overly-small>
+  </explain|The message size in the header was smaller than the minimal
+  message size.<space|1em>Sometimes, but not always, the message type
+  <var|type> and message size <var|size> are available (as exact
+  naturals).<space|1em>When they are not available, <var|type> and <var|size>
+  are <scm|#false> instead.<space|1em>This can only happen if the server or
+  connection to the server is buggy.>
+
+  <\explain>
+    <scm|logic:no-handler> <var|type> . <var|rest><index|logic:no-handler>
+  <|explain>
+    The received message of type <var|type> (as an integer) does not have a
+    corresponding message handler.<space|1em><var|rest> is currently
+    unspecified.
+  </explain>
+
+  <\explain>
+    <scm|logic:ill-formed> <var|type> . <var|rest><index|logic:ill-formed>
+  </explain|The received message of type (as an integer) is ill-formed
+  according to the message handler.<space|1em><var|rest> is currently
+  unspecified.>
+
+  Consider automatically reconnecting after
+  <scm|<scm|input:regular-end-of-file>> and
+  <scm|<scm|input:premature-end-of-file>>, to allow the server to restart
+  without having to manually restart every individual
+  application.<space|1em>To report errors, see the section
+  <reference|sec:error reporting> Error reporting.
+
+  <section|Ordering of injected errors and messages and sent messages>
+
+  This section describes how injected errors and messages and sent messages
+  are ordered with respect to each other in the default message queue
+  implementation.<space|1em>Messages are handled or corresponding
+  <scm|logic:no-handler> or <scm|logic:ill-formed> errors are injected in the
+  order that the messages are received.<space|1em>Before messages are read,
+  <scm|connection:connected> is injected.<space|1em>This error is injected at
+  most once.
+
+  <em|Soon> after all messages are read (and therefore
+  <with|font-shape|italic|soon> after all handled messages or corresponding
+  errors), the error <scm|input:regular-end-of-file>,
+  <scm|input:overly-small> or <scm|input:premature-end-of-file> is
+  injected.<space|1em>Only one of those errors can be injected for the entire
+  lifetime of the message queue.
+
+  Be aware that <em|soon> is not <em|immediate> here!<space|1em>For example,
+  it is possible for a message to be received, the port closed, a message
+  queued for sending, the closing of the port being detected by the write
+  fiber, <scm|input:regular-end-of-file> being injected from the write fiber
+  and the read fiber handling the received message, and the read fiber
+  exiting because the port is closed, in that order.
+
+  Messages are sent (and received on the other side) in the order they were
+  enqueued for sending.<space|1em>Likewise, the notify-sent callback of
+  enqueued messages are called in order.<space|1em>If the notify-sent
+  callback is called, it is before the message is received by the other
+  side.<space|1em>The message and its notify-sent callback are only received
+  by the other side and called after the message has been injected and
+  <scm|connection:connected> has been injected.<space|1em>It is possible for
+  the notify-sent callback to be called without the message being received by
+  the other side, e.g. if the port was closed during the notify-sent
+  callback.
+
+  If a message is received by the other side, all previously-sent messages
+  have be received before.<space|1em>If a notify-sent callback is invoked,
+  all notify-sent callbacks of previous messages have been invoked before,
+  except the messages that are eventually cancelled.
+
+  The errors <scm|logic:no-handler> and <scm|logic:ill-formed> are not fatal:
+  later messages can still be read and handled.<space|1em>If
+  <scm|connection:interrupted> is injected, no other errors are ever
+  injected, whether in the past or in the future.<space|1em>This error can
+  only be injected once.
+
+  <todo|I/O errors>
+
+  <todo|envelopes>
+
+  <section|Disconnecting><index|disconnecting>
+
+  A message queue can be closed with the <scm|close-queue!><index|close-queue!>
+  procedure from <scm|(gnu gnunet mq)>.<space|1em>In the default message
+  queue implementation, this asynchronuously closes the port and stops
+  associated fibers.<space|1em>Closing ports when they won't be used anymore
+  is important for limiting resource consumption, especially for servers that
+  can have many connections.<space|1em>Closing message queues is an
+  idempotent operation: closing a message queue twice is the same as closing
+  it once.<space|1em> If a message queue is closed before a connection could
+  be formed, <scm|connection:interrupted><index|connection:interrupted> is
+  injected instead of <scm|connection:connected> and
+  <scm|connection:regular-end-of-file>.
+
+  <section|Error reporting><label|sec:error reporting>
+
+  <index|error reporting>Errors can be reported with the procedure
+  <scm|report-error> from the module <scm|(gnu gnunet mq
+  error-reporting)><index|(gnu gnunet mq error-reporting)>.<space|1em>It can
+  be called as <scm|(report-error key argument ...)>, e.g. <scm|(report-error
+  'logic:no-handler 3)><index|report-error>.<space|1em>By default, it reports
+  the error to the current error port.<space|1em>If this is not desired, the
+  output can be sent to another port by setting the parameter
+  
<scm|textual-error-reporting-port><index|textual-error-reporting-port>.<space|1em>If
+  textual error reporting is not desired, the parameter
+  <scm|error-reporter><index|error-reporter> can be set to a procedure with
+  the same interface as <scm|report-error>.<space|1em>Such a procedure could
+  e.g. open a GUI dialog, sent the message to the system logger or ignore the
+  error.
+
+  Error messages are translated for the current locale.<todo|TODO actually
+  call bindtextdomain>
+</body>
+
+<\initial>
+  <\collection>
+    <associate|page-medium|paper>
+    <associate|save-aux|false>
+  </collection>
+</initial>
\ No newline at end of file

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]