aboutsummaryrefslogtreecommitdiff
path: root/doc/documentation/gnunet-c-tutorial.texi
diff options
context:
space:
mode:
Diffstat (limited to 'doc/documentation/gnunet-c-tutorial.texi')
-rw-r--r--doc/documentation/gnunet-c-tutorial.texi1559
1 files changed, 0 insertions, 1559 deletions
diff --git a/doc/documentation/gnunet-c-tutorial.texi b/doc/documentation/gnunet-c-tutorial.texi
deleted file mode 100644
index b3bcdf18a..000000000
--- a/doc/documentation/gnunet-c-tutorial.texi
+++ /dev/null
@@ -1,1559 +0,0 @@
1\input texinfo
2@c %**start of header
3@setfilename gnunet-c-tutorial.info
4@documentencoding UTF-8
5@settitle GNUnet C Tutorial
6@c @exampleindent 2
7@c %**end of header
8
9@include version.texi
10
11@copying
12Copyright @copyright{} 2001-2018 GNUnet e.V.
13
14Permission is granted to copy, distribute and/or modify this document
15under the terms of the GNU Free Documentation License, Version 1.3 or
16any later version published by the Free Software Foundation; with no
17Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A
18copy of the license is included in the section entitled ``GNU Free
19Documentation License''.
20
21A copy of the license is also available from the Free Software
22Foundation Web site at @url{http://www.gnu.org/licenses/fdl.html}.
23
24Alternately, this document is also available under the General
25Public License, version 3 or later, as published by the Free Software
26Foundation. A copy of the license is included in the section entitled
27``GNU General Public License''.
28
29A copy of the license is also available from the Free Software
30Foundation Web site at @url{http://www.gnu.org/licenses/gpl.html}.
31@end copying
32
33@dircategory Tutorial
34@direntry
35* GNUnet-C-Tutorial: (gnunet-c-tutorial). C Tutorial for GNunet
36@end direntry
37
38
39@titlepage
40@title GNUnet C Tutorial
41@subtitle A Tutorial for GNUnet @value{VERSION} (C version)
42@author The GNUnet Developers
43
44@page
45@vskip 0pt plus 1filll
46
47@insertcopying
48@end titlepage
49
50@contents
51
52@c **** TODO
53@c 1. Update content?
54@c 2. Either reference main documentation or
55@c 3. Merge this into main documentation
56
57@node Top
58@top Introduction
59
60This tutorials explains how to install GNUnet on a
61GNU/Linux system and gives an introduction on how
62GNUnet can be used to develop a Peer-to-Peer application.
63Detailed installation instructions for
64various operating systems and a detailed list of all
65dependencies can be found on our website at
66@uref{https://gnunet.org/installation} and in our
67Reference Documentation (GNUnet Handbook).
68
69Please read this tutorial carefully since every single step is
70important, and do not hesitate to contact the GNUnet team if you have
71any questions or problems! Visit this link in your webbrowser to learn
72how to contact the GNUnet team:
73@uref{https://gnunet.org/contact_information}
74
75@menu
76
77* Installing GNUnet:: Installing GNUnet
78* Introduction to GNUnet Architecture:: Introduction to GNUnet Architecture
79* First Steps with GNUnet:: First Steps with GNUnet
80* Developing Applications:: Developing Applications
81
82@detailmenu
83 --- The Detailed Node Listing ---
84
85Installing GNUnet
86
87* Obtaining a stable version::
88* Installing Build Tool Chain and Dependencies::
89* Obtaining the latest version from Git::
90* Compiling and Installing GNUnet::
91* Common Issues - Check your GNUnet installation::
92
93Introduction to GNUnet Architecture
94
95First Steps with GNUnet
96
97* Configure your peer::
98* Start a peer::
99* Monitor a peer::
100* Starting Two Peers by Hand::
101* Starting Peers Using the Testbed Service::
102
103Developing Applications
104
105* gnunet-ext::
106* Adapting the Template::
107* Writing a Client Application::
108* Writing a Service::
109* Interacting directly with other Peers using the CORE Service::
110* Storing peer-specific data using the PEERSTORE service::
111* Using the DHT::
112* Debugging with gnunet-arm::
113
114@end detailmenu
115@end menu
116
117@node Installing GNUnet
118@chapter Installing GNUnet
119
120First of all you have to install a current version of GNUnet.
121You can download a tarball of a stable version from GNU FTP mirrors
122or obtain the latest development version from our Git repository.
123
124Most of the time you should prefer to download the stable version
125since with the latest development version things can be broken,
126functionality can be changed or tests can fail. You should only use
127the development version if you know that you require a certain
128feature or a certain issue has been fixed since the last release.
129
130@menu
131* Obtaining a stable version::
132* Installing Build Tool Chain and Dependencies::
133* Obtaining the latest version from Git::
134* Compiling and Installing GNUnet::
135* Common Issues - Check your GNUnet installation::
136@end menu
137
138@node Obtaining a stable version
139@section Obtaining a stable version
140
141Download the tarball from
142@indicateurl{https://ftp.gnu.org/gnu/gnunet/gnunet-@value{VERSION}.tar.gz}.
143
144Make sure to download the associated @file{.sig} file and to verify the
145authenticity of the tarball against it, like this:
146
147@example
148$ wget https://ftp.gnu.org/gnu/gnunet/gnunet-@value{VERSION}.tar.gz.sig
149$ gpg --verify-files gnunet-@value{VERSION}.tar.gz.sig
150@end example
151
152@noindent
153If this command fails because you do not have the required public key,
154then you need to run the following command to import it:
155
156@example
157$ gpg --keyserver keys.gnupg.net --recv-keys 48426C7E
158@end example
159
160@noindent
161and rerun the @code{gpg --verify-files} command.
162
163@b{Note:}@
164@b{The pub key to sign the 0.10.1 release has been
165revoked}. You will get an error message stating that
166@b{there is no known public key or that it has been revoked}.
167The next release of GNUnet will have a valid signature
168again. We are sorry for the inconvenience this causes.
169Another possible source you could use is our
170"gnunet" git repository which, since the change from SVN to git in 2016,
171has mandatory signed commits by every developer.
172
173After verifying the signature you can extract the tarball.
174The resulting directory will be renamed to @file{gnunet}, which we will
175be using in the remainder of this document to refer to the
176root of the source directory.
177
178@example
179$ tar xvzf gnunet-@value{VERSION}.tar.gz
180$ mv gnunet-@value{VERSION} gnunet
181@end example
182
183@c FIXME: This can be irritating for the reader - First we say git should
184@c be avoid unless it is really required, and then we write this
185@c paragraph:
186@noindent
187However, please note that stable versions can be very outdated.
188As a developer you are @b{strongly} encouraged to use the version
189from @uref{https://gnunet.org/git/, git}.
190
191@node Installing Build Tool Chain and Dependencies
192@section Installing Build Tool Chain and Dependencies
193
194To successfully compile GNUnet, you need the tools to build GNUnet and
195the required dependencies. Please take a look at the
196GNUnet Reference Documentation
197(@pxref{Dependencies, The GNUnet Reference Documentation,, gnunet, The GNUnet Reference Documentation})
198for a list of required dependencies and
199(@pxref{Generic installation instructions, The GNUnet Reference Documentation,, gnunet, The GNUnet Reference Documentation})
200read its Installation chapter for specific instructions for
201your Operating System.
202Please check the notes at the end of the configure process about
203required dependencies.
204
205For GNUnet bootstrapping support and the HTTP(S) plugin you should
206install @uref{https://gnunet.org/gnurl, libgnurl}.
207For the filesharing service you should install at least one of the
208datastore backends (MySQL, SQlite and PostgreSQL are supported).
209
210@node Obtaining the latest version from Git
211@section Obtaining the latest version from Git
212
213The latest development version can be obtained from our Git repository.
214To get the code you need to have @code{Git} installed. Usually your
215Operating System package manager should provide a suitable distribution
216of git (otherwise check out Guix or Nix). If you are using an Operating
217System based on Debian's apt:
218
219@example
220$ sudo apt-get install git
221@end example
222
223This is required for obtaining the repository, which is achieved with
224the following command:
225
226@example
227$ git clone https://gnunet.org/git/gnunet
228@end example
229
230@noindent
231After cloning the repository, you have to execute the @file{bootstrap}
232script in the new directory:
233
234@example
235$ cd gnunet
236$ ./bootstrap
237@end example
238
239@noindent
240The remainder of this tutorial will assume that you have the
241Git branch ``master'' checked out.
242
243@node Compiling and Installing GNUnet
244@section Compiling and Installing GNUnet
245
246Note: This section is a duplication of the more in depth
247@pxref{GNUnet Installation Handbook, The GNUnet Reference Documentation,, gnunet, The GNUnet Reference Documentation}.
248
249First, you need to install libgnupgerror @geq{} 1.27 and
250libgcrypt @geq{} 1.7.6:
251
252@example
253$ export GNUPGFTP="https://www.gnupg.org/ftp/gcrypt"
254$ wget $GNUPGFTP/libgpg-error/libgpg-error-1.27.tar.bz2
255$ tar xf libgpg-error-1.27.tar.bz2
256$ cd libgpg-error-1.27
257$ ./configure
258$ make
259$ sudo make install
260$ cd ..
261@end example
262
263@example
264$ export GNUPGFTP="https://www.gnupg.org/ftp/gcrypt"
265$ wget $GNUPGFTP/libgcrypt/libgcrypt-1.7.6.tar.bz2
266$ tar xf libgcrypt-1.7.6.tar.bz2
267$ cd libgcrypt-1.7.6
268$ ./configure
269$ make
270$ sudo make install
271$ cd ..
272@end example
273
274@menu
275* Installation::
276@end menu
277
278@node Installation
279@subsection Installation
280Assuming all dependencies are installed, the following commands will
281compile and install GNUnet in your home directory. You can specify the
282directory where GNUnet will be installed by changing the
283@code{--prefix} value when calling @command{./configure}. If
284you do not specifiy a prefix, GNUnet is installed in the directory
285@file{/usr/local}. When developing new applications you may want
286to enable verbose logging by adding @code{--enable-logging=verbose}:
287
288@example
289$ export PREFIX=$HOME
290$ ./configure --prefix=$PREFIX --enable-logging
291$ make
292$ make install
293@end example
294
295@noindent
296After installing GNUnet you have to add your GNUnet installation
297to your path environmental variable. In addition you have to
298create the @file{.config} directory in your home directory
299(unless it already exists) where GNUnet stores its data and an
300empty GNUnet configuration file:
301
302@example
303$ export PATH=$PATH:$PREFIX/bin
304$ echo export PATH=$PREFIX/bin:\\$PATH >> ~/.bashrc
305$ mkdir ~/.config/
306$ touch ~/.config/gnunet.conf
307@end example
308
309@node Common Issues - Check your GNUnet installation
310@section Common Issues - Check your GNUnet installation
311
312You should check your installation to ensure that installing GNUnet
313was successful up to this point. You should be able to access GNUnet's
314binaries and run GNUnet's self check.
315
316@example
317$ which gnunet-arm
318$PREFIX/bin/gnunet-arm
319@end example
320
321@noindent
322should return $PREFIX/bin/gnunet-arm (where $PREFIX is the location
323you have set earlier). It should be located in your
324GNUnet installation and the output should not be empty.
325
326If you see an output like:
327
328@example
329$ which gnunet-arm
330@end example
331
332@noindent
333check your PATH variable to ensure GNUnet's @file{bin} directory is
334included.
335
336GNUnet provides tests for all of its subcomponents. Assuming you have
337successfully built GNUnet, run
338
339@example
340$ cd gnunet
341$ make check
342@end example
343
344@noindent
345to execute tests for all components. @command{make check} traverses all
346subdirectories in @file{src}. For every subdirectory you should
347get a message like this:
348
349@example
350make[2]: Entering directory `/home/$USER/gnunet/contrib'
351PASS: test_gnunet_prefix
352=============
3531 test passed
354=============
355@end example
356
357@node Introduction to GNUnet Architecture
358@chapter Introduction to GNUnet Architecture
359
360GNUnet is organized in layers and services. Each service is composed of a
361main service implementation and a client library for other programs to use
362the service's functionality, described by an API.
363@c This approach is shown in
364@c FIXME: enable this once the commented block below works:
365@c figure~\ref fig:service.
366Some services provide an additional command line tool to enable the user
367to interact with the service.
368
369Very often it is other GNUnet services that will use these APIs to build
370the higher layers of GNUnet on top of the lower ones. Each layer expands
371or extends the functionality of the service below (for instance, to build
372a mesh on top of a DHT).
373@c FXIME: See comment above.
374@c See figure ~\ref fig:interaction for an illustration of this approach.
375
376@c ** @image filename[, width[, height[, alttext[, extension]]]]
377@c FIXME: Texlive (?) 20112 makes the assumption that this means
378@c 'images/OBJECTNAME.txt' but later versions of it (2017) use this
379@c syntax as described below.
380@c TODO: Checkout the makedoc script Guile uses.
381
382@c FIXME!!!
383@c @image{images/gnunet-tutorial-service,,5in,Service with API and network protocol,.png}
384@c @image{images/gnunet-tutorial-system,,5in,The layered system architecture of GNUnet,.png}
385
386@c \begin{figure}[!h]
387@c \begin{center}
388@c % \begin{subfigure}
389@c \begin{subfigure}[b]{0.3\textwidth}
390@c \centering
391@c \includegraphics[width=\textwidth]{figs/Service.pdf}
392@c \caption{Service with API and network protocol}
393@c \label{fig:service}
394@c \end{subfigure}
395@c ~~~~~~~~~~
396@c \begin{subfigure}[b]{0.3\textwidth}
397@c \centering
398@c \includegraphics[width=\textwidth]{figs/System.pdf}
399@c \caption{Service interaction}
400@c \label{fig:interaction}
401@c \end{subfigure}
402@c \end{center}
403@c \caption{GNUnet's layered system architecture}
404@c \end{figure}
405
406The main service implementation runs as a standalone process in the
407Operating System and the client code runs as part of the client program,
408so crashes of a client do not affect the service process or other clients.
409The service and the clients communicate via a message protocol to be
410defined and implemented by the programmer.
411
412@node First Steps with GNUnet
413@chapter First Steps with GNUnet
414
415@menu
416* Configure your peer::
417* Start a peer::
418* Monitor a peer::
419* Starting Two Peers by Hand::
420* Starting Peers Using the Testbed Service::
421@end menu
422
423@node Configure your peer
424@section Configure your peer
425
426First of all we need to configure your peer. Each peer is started with
427a configuration containing settings for GNUnet itself and its services.
428This configuration is based on the default configuration shipped with
429GNUnet and can be modified. The default configuration is located in the
430@file{$PREFIX/share/gnunet/config.d} directory. When starting a peer, you
431can specify a customized configuration using the the @command{-c} command
432line switch when starting the ARM service and all other services. When
433using a modified configuration the default values are loaded and only
434values specified in the configuration file will replace the default
435values.
436
437Since we want to start additional peers later, we need some modifications
438from the default configuration. We need to create a separate service
439home and a file containing our modifications for this peer:
440
441@example
442$ mkdir ~/gnunet1/
443$ touch peer1.conf
444@end example
445
446@noindent
447Now add the following lines to @file{peer1.conf} to use this directory.
448For simplified usage we want to prevent the peer to connect to the GNUnet
449network since this could lead to confusing output. This modifications
450will replace the default settings:
451
452@example
453[PATHS]
454# Use this directory to store GNUnet data
455GNUNET_HOME = ~/gnunet1/
456[hostlist]
457# prevent bootstrapping
458SERVERS =
459@end example
460
461@node Start a peer
462@section Start a peer
463Each GNUnet instance (called peer) has an identity (peer ID) based on a
464cryptographic public private key pair. The peer ID is the printable hash
465of the public key.
466
467GNUnet services are controlled by a master service, the so called
468@dfn{Automatic Restart Manager} (ARM). ARM starts, stops and even
469restarts services automatically or on demand when a client connects.
470You interact with the ARM service using the @command{gnunet-arm} tool.
471GNUnet can then be started with @command{gnunet-arm -s} and stopped with
472@command{gnunet-arm -e}. An additional service not automatically started
473can be started using @command{gnunet-arm -i <service name>} and stopped
474using @command{gnunet-arm -k <servicename>}.
475
476Once you have started your peer, you can use many other GNUnet commands
477to interact with it. For example, you can run:
478
479@example
480$ gnunet-peerinfo -s
481@end example
482
483@noindent
484to obtain the public key of your peer.
485
486You should see an output containing the peer ID similar to:
487
488@example
489I am peer `0PA02UVRKQTS2C .. JL5Q78F6H0B1ACPV1CJI59MEQUMQCC5G'.
490@end example
491
492@node Monitor a peer
493@section Monitor a peer
494
495In this section, we will monitor the behaviour of our peer's DHT
496service with respect to a specific key. First we will start
497GNUnet and then start the DHT service and use the DHT monitor tool
498to monitor the PUT and GET commands we issue ussing the
499@command{gnunet-dht-put} and @command{gnunet-dht-get} commands.
500Using the ``monitor'' line given below, you can observe the behavior
501of your own peer's DHT with respect to the specified KEY:
502
503@example
504# start gnunet with all default services:
505$ gnunet-arm -c ~/peer1.conf -s
506# start DHT service:
507$ gnunet-arm -c ~/peer1.conf -i dht
508$ cd ~/gnunet/src/dht;
509$ ./gnunet-dht-monitor -c ~/peer1.conf -k KEY
510@end example
511
512@noindent
513Now open a separate terminal and change again to
514the @file{gnunet/src/dht} directory:
515
516@example
517$ cd ~/gnunet/src/dht
518# put VALUE under KEY in the DHT:
519$ ./gnunet-dht-put -c ~/peer1.conf -k KEY -d VALUE
520# get key KEY from the DHT:
521$ ./gnunet/src/dht/gnunet-dht-get -c ~/peer1.conf -k KEY
522# print statistics about current GNUnet state:
523$ gnunet-statistics -c ~/peer1.conf
524# print statistics about DHT service:
525$ gnunet-statistics -c ~/peer1.conf -s dht
526@end example
527
528@node Starting Two Peers by Hand
529@section Starting Two Peers by Hand
530
531This section describes how to start two peers on the same machine by hand.
532The process is rather painful, but the description is somewhat
533instructive. In practice, you might prefer the automated method
534(@pxref{Starting Peers Using the Testbed Service}).
535
536@menu
537* Setup a second peer::
538* Start the second peer and connect the peers::
539* How to connect manually::
540@end menu
541
542@node Setup a second peer
543@subsection Setup a second peer
544We will now start a second peer on your machine.
545For the second peer, you will need to manually create a modified
546configuration file to avoid conflicts with ports and directories.
547A peers configuration file is by default located
548in @file{~/.gnunet/gnunet.conf}. This file is typically very short
549or even empty as only the differences to the defaults need to be
550specified. The defaults are located in many files in the
551@file{$PREFIX/share/gnunet/config.d} directory.
552
553To configure the second peer, use the files
554@file{$PREFIX/share/gnunet/config.d} as a template for your main
555configuration file:
556
557@example
558$ cat $PREFIX/share/gnunet/config.d/*.conf > peer2.conf
559@end example
560
561@noindent
562Now you have to edit @file{peer2.conf} and change:
563
564@itemize
565@item @code{GNUNET\_TEST\_HOME} under @code{PATHS}
566@item Every (uncommented) value for ``@code{PORT}'' (add 10000) in any
567section (the option may be commented out if @code{PORT} is
568prefixed by "\#", in this case, UNIX domain sockets are used
569and the PORT option does not need to be touched)
570@item Every value for ``@code{UNIXPATH}'' in any section
571(e.g. by adding a "-p2" suffix)
572@end itemize
573
574to a fresh, unique value. Make sure that the PORT numbers stay
575below 65536. From now on, whenever you interact with the second peer,
576you need to specify @command{-c peer2.conf} as an additional
577command line argument.
578
579Now, generate the 2nd peer's private key:
580
581@example
582$ gnunet-peerinfo -s -c peer2.conf
583@end example
584
585@noindent
586This may take a while, generate entropy using your keyboard or mouse
587as needed. Also, make sure the output is different from the
588gnunet-peerinfo output for the first peer (otherwise you made an
589error in the configuration).
590
591@node Start the second peer and connect the peers
592@subsection Start the second peer and connect the peers
593
594Then, you can start a second peer using:
595
596@example
597$ gnunet-arm -c peer2.conf -s
598$ gnunet-arm -c peer2.conf -i dht
599$ ~/gnunet/src/dht/gnunet-dht-put -c peer2.conf -k KEY -d VALUE
600$ ~/gnunet/src/dht/gnunet-dht-get -c peer2.conf -k KEY
601@end example
602
603If you want the two peers to connect, you have multiple options:
604
605@itemize
606@item UDP neighbour discovery (automatic)
607@item Setup a bootstrap server
608@item Connect manually
609@end itemize
610
611To setup peer 1 as bootstrapping server change the configuration of
612the first one to be a hostlist server by adding the following lines to
613@file{peer1.conf} to enable bootstrapping server:
614
615@example
616[hostlist]
617OPTIONS = -p
618@end example
619
620@noindent
621Then change @file{peer2.conf} and replace the ``@code{SERVERS}''
622line in the ``@code{[hostlist]}'' section with
623``@code{http://localhost:8080/}''. Restart both peers using:
624
625@example
626# stop first peer
627$ gnunet-arm -c peer1.conf -e
628# start first peer
629$ gnunet-arm -c peer1.conf -s
630# start second peer
631$ gnunet-arm -c peer2.conf -s
632@end example
633
634@noindent
635Note that if you start your peers without changing these settings, they
636will use the ``global'' hostlist servers of the GNUnet P2P network and
637likely connect to those peers. At that point, debugging might become
638tricky as you're going to be connected to many more peers and would
639likely observe traffic and behaviors that are not explicitly controlled
640by you.
641
642@node How to connect manually
643@subsection How to connect manually
644
645If you want to use the @code{peerinfo} tool to connect your
646peers, you should:
647
648@itemize
649@item Set @code{IMMEDIATE_START = NO} in section @code{hostlist}
650(to not connect to the global GNUnet)
651@item Start both peers running @command{gnunet-arm -c peer1.conf -s}
652and @command{gnunet-arm -c peer2.conf -s}
653@item Get @code{HELLO} message of the first peer running
654@command{gnunet-peerinfo -c peer1.conf -g}
655@item Give the output to the second peer by running
656@command{gnunet-peerinfo -c peer2.conf -p '<output>'}
657@end itemize
658
659Check that they are connected using @command{gnunet-core -c peer1.conf},
660which should give you the other peer's peer identity:
661
662@example
663$ gnunet-core -c peer1.conf
664Peer `9TVUCS8P5A7ILLBGO6 [...shortened...] 1KNBJ4NGCHP3JPVULDG'
665@end example
666
667@node Starting Peers Using the Testbed Service
668@section Starting Peers Using the Testbed Service
669@c \label{sec:testbed}
670
671GNUnet's testbed service is used for testing scenarios where
672a number of peers are to be started. The testbed can manage peers
673on a single host or on multiple hosts in a distributed fashion.
674On a single affordable computer, it should be possible to run
675around tens of peers without drastically increasing the load on the
676system.
677
678The testbed service can be access through its API
679@file{include/gnunet\_testbed\_service.h}. The API provides many
680routines for managing a group of peers. It also provides a helper
681function @code{GNUNET\_TESTBED\_test\_run()} to quickly setup a
682minimalistic testing environment on a single host.
683
684This function takes a configuration file which will be used as a
685template configuration for the peers. The testbed takes care of
686modifying relevant options in the peers' configuration such as
687@code{SERVICEHOME}, @code{PORT}, @code{UNIXPATH} to unique values
688so that peers run without running into conflicts. It also checks
689and assigns the ports in configurations only if they are free.
690
691Additionally, the testbed service also reads its options from the
692same configuration file. Various available options and details
693about them can be found in the testbed default configuration file
694@file{src/testbed/testbed.conf}.
695
696With the testbed API, a sample test case can be structured as follows:
697
698@example
699@verbatiminclude testbed_test.c
700@end example
701
702@noindent
703The source code for the above listing can be found at
704@uref{https://gnunet.org/git/gnunet.git/tree/doc/
705documentation/testbed_test.c}
706or in the @file{doc/documentation/} folder of your repository check-out.
707After installing GNUnet, the above source code can be compiled as:
708
709@example
710$ export CPPFLAGS="-I/path/to/gnunet/headers"
711$ export LDFLAGS="-L/path/to/gnunet/libraries"
712$ gcc $CPPFLAGS $LDFLAGS -o testbed-test testbed_test.c \
713 -lgnunettestbed -lgnunetdht -lgnunetutil
714# Generate (empty) configuration
715$ touch template.conf
716# run it (press CTRL-C to stop)
717$ ./testbed-test
718@end example
719
720@noindent
721The @code{CPPFLAGS} and @code{LDFLAGS} are necessary if GNUnet
722is installed into a different directory other than @file{/usr/local}.
723
724All of testbed API's peer management functions treat management
725actions as operations and return operation handles. It is expected
726that the operations begin immediately, but they may get delayed (to
727balance out load on the system). The program using the API then has
728to take care of marking the operation as ``done'' so that its
729associated resources can be freed immediately and other waiting
730operations can be executed. Operations will be canceled if they are
731marked as ``done'' before their completion.
732
733An operation is treated as completed when it succeeds or fails.
734Completion of an operation is either conveyed as events through
735@dfn{controller event callback} or through respective
736@dfn{operation completion callbacks}.
737In functions which support completion notification
738through both controller event callback and operation
739completion callback, first the controller event callback will be
740called. If the operation is not marked as done in that callback
741or if the callback is given as NULL when creating the operation,
742the operation completion callback will be called. The API
743documentation shows which event are to be expected in the
744controller event notifications. It also documents any exceptional
745behaviour.
746
747Once the peers are started, test cases often need to connect
748some of the peers' services. Normally, opening a connect to
749a peer's service requires the peer's configuration. While using
750testbed, the testbed automatically generates per-peer configuration.
751Accessing those configurations directly through file system is
752discouraged as their locations are dynamically created and will be
753different among various runs of testbed. To make access to these
754configurations easy, testbed API provides the function
755@code{GNUNET\_TESTBED\_service\_connect()}. This function fetches
756the configuration of a given peer and calls the @dfn{Connect Adapter}.
757In the example code, it is the @code{dht\_ca}. A connect adapter is
758expected to open the connection to the needed service by using the
759provided configuration and return the created service connection handle.
760Successful connection to the needed service is signaled through
761@code{service\_connect\_comp\_cb}.
762
763A dual to connect adapter is the @dfn{Disconnect Adapter}. This callback
764is called after the connect adapter has been called when the operation
765from @code{GNUNET\_TESTBED\_service\_connect()} is marked as ``done''.
766It has to disconnect from the service with the provided service
767handle (@code{op\_result}).
768
769Exercise: Find out how many peers you can run on your system.
770
771Exercise: Find out how to create a 2D torus topology by changing the
772options in the configuration file.
773@xref{Supported Topologies, The GNUnet Reference Documentation ,, gnunet, The GNUnet Reference Documentation},
774then use the DHT API to store and retrieve values in the network.
775
776@node Developing Applications
777@chapter Developing Applications
778
779@menu
780* gnunet-ext::
781* Adapting the Template::
782* Writing a Client Application::
783* Writing a Service::
784* Interacting directly with other Peers using the CORE Service::
785* Storing peer-specific data using the PEERSTORE service::
786* Using the DHT::
787* Debugging with gnunet-arm::
788@end menu
789
790@node gnunet-ext
791@section gnunet-ext
792To develop a new peer-to-peer application or to extend GNUnet we provide
793a template build system for writing GNUnet extensions in C. It can be
794obtained as follows:
795
796@example
797$ git clone https://gnunet.org/git/gnunet-ext
798$ cd gnunet-ext/
799$ ./bootstrap
800$ ./configure --prefix=$PREFIX --with-gnunet=$PREFIX
801$ make
802$ make install
803$ make check
804@end example
805
806@noindent
807The GNUnet ext template includes examples and a working buildsystem
808for a new GNUnet service. A common GNUnet service consists of the
809following parts which will be discussed in detail in the remainder
810of this document. The functionality of a GNUnet service is implemented in:
811
812@itemize
813@item the GNUnet service (gnunet-ext/src/ext/gnunet-service-ext.c)
814@item the client API (gnunet-ext/src/ext/ext_api.c)
815@item the client application using the service API
816(gnunet-ext/src/ext/gnunet-ext.c)
817@end itemize
818
819The interfaces for these entities are defined in:
820
821@itemize
822@item client API interface (gnunet-ext/src/ext/ext.h)
823@item the service interface (gnunet-ext/src/include/gnunet_service_SERVICE.h)
824@item the P2P protocol (gnunet-ext/src/include/gnunet_protocols_ext.h)
825@end itemize
826
827
828In addition the ext systems provides:
829
830@itemize
831@item a test testing the API (gnunet-ext/src/ext/test_ext_api.c)
832@item a configuration template for the service
833(gnunet-ext/src/ext/ext.conf.in)
834@end itemize
835
836@node Adapting the Template
837@section Adapting the Template
838
839The first step for writing any extension with a new service is to
840ensure that the @file{ext.conf.in} file contains entries for the
841@code{UNIXPATH}, @code{PORT} and @code{BINARY} for the service in a
842section named after the service.
843
844If you want to adapt the template rename the @file{ext.conf.in} to
845match your services name, you have to modify the @code{AC\_OUTPUT}
846section in @file{configure.ac} in the @file{gnunet-ext} root.
847
848@node Writing a Client Application
849@section Writing a Client Application
850
851When writing any client application (for example, a command-line
852tool), the basic structure is to start with the
853@code{GNUNET\_PROGRAM\_run} function. This function will parse
854command-line options, setup the scheduler and then invoke the
855@code{run} function (with the remaining non-option arguments)
856and a handle to the parsed configuration (and the configuration
857file name that was used, which is typically not needed):
858
859@example
860@verbatiminclude tutorial-examples/001.c
861@end example
862
863@menu
864* Handling command-line options::
865* Writing a Client Library::
866* Writing a user interface::
867@end menu
868
869@node Handling command-line options
870@subsection Handling command-line options
871
872Options can then be added easily by adding global variables and
873expanding the @code{options} array. For example, the following would
874add a string-option and a binary flag (defaulting to @code{NULL} and
875@code{GNUNET\_NO} respectively):
876
877@example
878@verbatiminclude tutorial-examples/002.c
879@end example
880
881Issues such as displaying some helpful text describing options using
882the @code{--help} argument and error handling are taken care of when
883using this approach. Other @code{GNUNET\_GETOPT\_}-functions can be used
884to obtain integer value options, increment counters, etc. You can
885even write custom option parsers for special circumstances not covered
886by the available handlers. To check if an argument was specified by the
887user you initialize the variable with a specific value (e.g. NULL for
888a string and GNUNET\_SYSERR for a integer) and check after parsing
889happened if the values were modified.
890
891Inside the @code{run} method, the program would perform the
892application-specific logic, which typically involves initializing and
893using some client library to interact with the service. The client
894library is supposed to implement the IPC whereas the service provides
895more persistent P2P functions.
896
897Exercise: Add a few command-line options and print them inside
898of @code{run}. What happens if the user gives invalid arguments?
899
900@node Writing a Client Library
901@subsection Writing a Client Library
902
903The first and most important step in writing a client library is to
904decide on an API for the library. Typical API calls include
905connecting to the service, performing application-specific requests
906and cleaning up. Many examples for such service APIs can be found
907in the @file{gnunet/src/include/gnunet\_*\_service.h} files.
908
909Then, a client-service protocol needs to be designed. This typically
910involves defining various message formats in a header that will be
911included by both the service and the client library (but is otherwise
912not shared and hence located within the service's directory and not
913installed by @command{make install}). Each message must start with a
914@code{struct GNUNET\_MessageHeader} and must be shorter than 64k. By
915convention, all fields in IPC (and P2P) messages must be in big-endian
916format (and thus should be read using @code{ntohl} and similar
917functions and written using @code{htonl} and similar functions).
918Unique message types must be defined for each message struct in the
919@file{gnunet\_protocols.h} header (or an extension-specific include
920file).
921
922@menu
923* Connecting to the Service::
924* Sending messages::
925* Receiving Replies from the Service::
926@end menu
927
928@node Connecting to the Service
929@subsubsection Connecting to the Service
930
931Before a client library can implement the application-specific protocol
932with the service, a connection must be created:
933
934@example
935@verbatiminclude tutorial-examples/003.c
936@end example
937
938@noindent
939As a result a @code{GNUNET\_MQ\_Handle} is returned
940which can to used henceforth to transmit messages to the service.
941The complete MQ API can be found in @file{gnunet\_mq\_lib.h}.
942The @code{hanlders} array in the example above is incomplete.
943Here is where you will define which messages you expect to
944receive from the service, and which functions handle them.
945The @code{error\_cb} is a function that is to be called whenever
946there are errors communicating with the service.
947
948@node Sending messages
949@subsubsection Sending messages
950
951In GNUnet, messages are always sent beginning with a
952@code{struct GNUNET\_MessageHeader} in big endian format.
953This header defines the size and the type of the
954message, the payload follows after this header.
955
956@example
957@verbatiminclude tutorial-examples/004.c
958@end example
959
960@noindent
961Existing message types are defined in @file{gnunet\_protocols.h}.
962A common way to create a message is with an envelope:
963
964@example
965@verbatiminclude tutorial-examples/005.c
966@end example
967
968@noindent
969Exercise: Define a message struct that includes a 32-bit
970unsigned integer in addition to the standard GNUnet MessageHeader.
971Add a C struct and define a fresh protocol number for your message.
972Protocol numbers in gnunet-ext are defined
973in @file{gnunet-ext/src/include/gnunet_protocols_ext.h}
974
975Exercise: Find out how you can determine the number of messages
976in a message queue.
977
978Exercise: Find out how you can determine when a message you
979have queued was actually transmitted.
980
981Exercise: Define a helper function to transmit a 32-bit
982unsigned integer (as payload) to a service using some given client
983handle.
984
985@node Receiving Replies from the Service
986@subsubsection Receiving Replies from the Service
987
988Clients can receive messages from the service using the handlers
989specified in the @code{handlers} array we specified when connecting
990to the service. Entries in the the array are usually created using
991one of two macros, depending on whether the message is fixed size
992or variable size. Variable size messages are managed using two
993callbacks, one to check that the message is well-formed, the other
994to actually process the message. Fixed size messages are fully
995checked by the MQ-logic, and thus only need to provide the handler
996to process the message. Note that the prefixes @code{check\_}
997and @code{handle\_} are mandatory.
998
999@example
1000@verbatiminclude tutorial-examples/006.c
1001@end example
1002
1003@noindent
1004Exercise: Expand your helper function to receive a response message
1005(for example, containing just the @code{struct GNUnet MessageHeader}
1006without any payload). Upon receiving the service's response, you
1007should call a callback provided to your helper function's API.
1008
1009Exercise: Figure out where you can pass values to the
1010closures (@code{cls}).
1011
1012@node Writing a user interface
1013@subsection Writing a user interface
1014
1015Given a client library, all it takes to access a service now is to
1016combine calls to the client library with parsing command-line
1017options.
1018
1019Exercise: Call your client API from your @code{run()} method in your
1020client application to send a request to the service. For example,
1021send a 32-bit integer value based on a number given at the
1022command-line to the service.
1023
1024@node Writing a Service
1025@section Writing a Service
1026
1027Before you can test the client you've written so far, you'll
1028need to also implement the corresponding service.
1029
1030@menu
1031* Code Placement::
1032* Starting a Service::
1033@end menu
1034
1035@node Code Placement
1036@subsection Code Placement
1037
1038New services are placed in their own subdirectory under
1039@file{gnunet/src}. This subdirectory should contain the API
1040implementation file @file{SERVICE\_api.c}, the description of
1041the client-service protocol @file{SERVICE.h} and P2P protocol
1042@file{SERVICE\_protocol.h}, the implementation of the service itself
1043@file{gnunet-service-SERVICE.h} and several files for tests,
1044including test code and configuration files.
1045
1046@node Starting a Service
1047@subsection Starting a Service
1048
1049The key API definition for creating a service is the
1050@code{GNUNET\_SERVICE\_MAIN} macro:
1051
1052@example
1053@verbatiminclude tutorial-examples/007.c
1054@end example
1055
1056@noindent
1057In addition to the service name and flags, the macro takes three
1058functions, typically called @code{run}, @code{client\_connect\_cb} and
1059@code{client\_disconnect\_cb} as well as an array of message handlers
1060that will be called for incoming messages from clients.
1061
1062A minimal version of the three central service funtions would look
1063like this:
1064
1065@example
1066@verbatiminclude tutorial-examples/008.c
1067@end example
1068
1069@noindent
1070Exercise: Write a stub service that processes no messages at all
1071in your code. Create a default configuration for it, integrate it
1072with the build system and start the service from
1073@command{gnunet-service-arm} using @command{gnunet-arm -i NAME}.
1074
1075Exercise: Figure out how to set the closure (@code{cls}) for handlers
1076of a service.
1077
1078Exercise: Figure out how to send messages from the service back to the
1079client.
1080
1081Each handler function in the service @b{must} eventually (possibly in some
1082asynchronous continuation) call
1083@code{GNUNET\_SERVICE\_client\_continue()}. Only after this call
1084additional messages from the same client may
1085be processed. This way, the service can throttle processing messages
1086from the same client.
1087
1088Exercise: Change the service to ``handle'' the message from your
1089client (for now, by printing a message). What happens if you
1090forget to call @code{GNUNET\_SERVICE\_client\_continue()}?
1091
1092@node Interacting directly with other Peers using the CORE Service
1093@section Interacting directly with other Peers using the CORE Service
1094
1095FIXME: This section still needs to be updated to the lastest API!
1096
1097One of the most important services in GNUnet is the @code{CORE} service
1098managing connections between peers and handling encryption between peers.
1099
1100One of the first things any service that extends the P2P protocol
1101typically does is connect to the @code{CORE} service using:
1102
1103@example
1104@verbatiminclude tutorial-examples/009.c
1105@end example
1106
1107@menu
1108* New P2P connections::
1109* Receiving P2P Messages::
1110* Sending P2P Messages::
1111* End of P2P connections::
1112@end menu
1113
1114@node New P2P connections
1115@subsection New P2P connections
1116
1117Before any traffic with a different peer can be exchanged, the peer must
1118be known to the service. This is notified by the @code{CORE}
1119@code{connects} callback, which communicates the identity of the new
1120peer to the service:
1121
1122@example
1123@verbatiminclude tutorial-examples/010.c
1124@end example
1125
1126@noindent
1127Note that whatever you return from @code{connects} is given as the
1128@code{cls} argument to the message handlers for messages from
1129the respective peer.
1130
1131Exercise: Create a service that connects to the @code{CORE}. Then
1132start (and connect) two peers and print a message once your connect
1133callback is invoked.
1134
1135@node Receiving P2P Messages
1136@subsection Receiving P2P Messages
1137
1138To receive messages from @code{CORE}, you pass the desired
1139@code{handlers} to the @code{GNUNET\_CORE\_connect()} function,
1140just as we showed for services.
1141
1142It is your responsibility to process messages fast enough or
1143to implement flow control. If an application does not process
1144CORE messages fast enough, CORE will randomly drop messages
1145to not keep a very long queue in memory.
1146
1147Exercise: Start one peer with a new service that has a message
1148handler and start a second peer that only has your ``old'' service
1149without message handlers. Which ``connect'' handlers are invoked when
1150the two peers are connected? Why?
1151
1152@node Sending P2P Messages
1153@subsection Sending P2P Messages
1154
1155You can transmit messages to other peers using the @code{mq} you were
1156given during the @code{connect} callback. Note that the @code{mq}
1157automatically is released upon @code{disconnect} and that you must
1158not use it afterwards.
1159
1160It is your responsibility to not over-fill the message queue, GNUnet
1161will send the messages roughly in the order given as soon as possible.
1162
1163Exercise: Write a service that upon connect sends messages as
1164fast as possible to the other peer (the other peer should run a
1165service that ``processes'' those messages). How fast is the
1166transmission? Count using the STATISTICS service on both ends. Are
1167messages lost? How can you transmit messages faster? What happens if
1168you stop the peer that is receiving your messages?
1169
1170@node End of P2P connections
1171@subsection End of P2P connections
1172
1173If a message handler returns @code{GNUNET\_SYSERR}, the remote
1174peer shuts down or there is an unrecoverable network
1175disconnection, CORE notifies the service that the peer disconnected.
1176After this notification no more messages will be received from the
1177peer and the service is no longer allowed to send messages to the peer.
1178The disconnect callback looks like the following:
1179
1180@example
1181@verbatiminclude tutorial-examples/011.c
1182@end example
1183
1184@noindent
1185Exercise: Fix your service to handle peer disconnects.
1186
1187@node Storing peer-specific data using the PEERSTORE service
1188@section Storing peer-specific data using the PEERSTORE service
1189
1190GNUnet's PEERSTORE service offers a persistorage for arbitrary
1191peer-specific data. Other GNUnet services can use the PEERSTORE
1192to store, retrieve and monitor data records. Each data record
1193stored with PEERSTORE contains the following fields:
1194
1195@itemize
1196@item subsystem: Name of the subsystem responsible for the record.
1197@item peerid: Identity of the peer this record is related to.
1198@item key: a key string identifying the record.
1199@item value: binary record value.
1200@item expiry: record expiry date.
1201@end itemize
1202
1203The first step is to start a connection to the PEERSTORE service:
1204@example
1205@verbatiminclude tutorial-examples/012.c
1206@end example
1207
1208The service handle @code{peerstore_handle} will be needed for
1209all subsequent PEERSTORE operations.
1210
1211@menu
1212* Storing records::
1213* Retrieving records::
1214* Monitoring records::
1215* Disconnecting from PEERSTORE::
1216@end menu
1217
1218@node Storing records
1219@subsection Storing records
1220
1221To store a new record, use the following function:
1222
1223@example
1224@verbatiminclude tutorial-examples/013.c
1225@end example
1226
1227@noindent
1228The @code{options} parameter can either be
1229@code{GNUNET_PEERSTORE_STOREOPTION_MULTIPLE} which means that multiple
1230values can be stored under the same key combination
1231(subsystem, peerid, key), or @code{GNUNET_PEERSTORE_STOREOPTION_REPLACE}
1232which means that PEERSTORE will replace any existing values under the
1233given key combination (subsystem, peerid, key) with the new given value.
1234
1235The continuation function @code{cont} will be called after the store
1236request is successfully sent to the PEERSTORE service. This does not
1237guarantee that the record is successfully stored, only that it was
1238received by the service.
1239
1240The @code{GNUNET_PEERSTORE_store} function returns a handle to the store
1241operation. This handle can be used to cancel the store operation only
1242before the continuation function is called:
1243
1244@example
1245@verbatiminclude tutorial-examples/013.1.c
1246@end example
1247
1248@node Retrieving records
1249@subsection Retrieving records
1250
1251To retrieve stored records, use the following function:
1252
1253@example
1254@verbatiminclude tutorial-examples/014.c
1255@end example
1256
1257@noindent
1258The values of @code{peer} and @code{key} can be @code{NULL}. This
1259allows the iteration over values stored under any of the following
1260key combinations:
1261
1262@itemize
1263@item (subsystem)
1264@item (subsystem, peerid)
1265@item (subsystem, key)
1266@item (subsystem, peerid, key)
1267@end itemize
1268
1269The @code{callback} function will be called once with each retrieved
1270record and once more with a @code{NULL} record to signal the end of
1271results.
1272
1273The @code{GNUNET_PEERSTORE_iterate} function returns a handle to the
1274iterate operation. This handle can be used to cancel the iterate
1275operation only before the callback function is called with a
1276@code{NULL} record.
1277
1278@node Monitoring records
1279@subsection Monitoring records
1280
1281PEERSTORE offers the functionality of monitoring for new records
1282stored under a specific key combination (subsystem, peerid, key).
1283To start the monitoring, use the following function:
1284
1285@example
1286@verbatiminclude tutorial-examples/015.c
1287@end example
1288
1289@noindent
1290Whenever a new record is stored under the given key combination,
1291the @code{callback} function will be called with this new
1292record. This will continue until the connection to the PEERSTORE
1293service is broken or the watch operation is canceled:
1294
1295@example
1296@verbatiminclude tutorial-examples/016.c
1297@end example
1298
1299@node Disconnecting from PEERSTORE
1300@subsection Disconnecting from PEERSTORE
1301
1302When the connection to the PEERSTORE service is no longer needed,
1303disconnect using the following function:
1304
1305@example
1306@verbatiminclude tutorial-examples/017.c
1307@end example
1308
1309@noindent
1310If the @code{sync_first} flag is set to @code{GNUNET_YES},
1311the API will delay the disconnection until all store requests
1312are received by the PEERSTORE service. Otherwise, it will
1313disconnect immediately.
1314
1315@node Using the DHT
1316@section Using the DHT
1317
1318The DHT allows to store data so other peers in the P2P network can
1319access it and retrieve data stored by any peers in the network.
1320This section will explain how to use the DHT. Of course, the first
1321thing to do is to connect to the DHT service:
1322
1323@example
1324@verbatiminclude tutorial-examples/018.c
1325@end example
1326
1327@noindent
1328The second parameter indicates how many requests in parallel to expect.
1329It is not a hard limit, but a good approximation will make the DHT more
1330efficient.
1331
1332@menu
1333* Storing data in the DHT::
1334* Obtaining data from the DHT::
1335* Implementing a block plugin::
1336* Monitoring the DHT::
1337@end menu
1338
1339@node Storing data in the DHT
1340@subsection Storing data in the DHT
1341Since the DHT is a dynamic environment (peers join and leave frequently)
1342the data that we put in the DHT does not stay there indefinitely. It is
1343important to ``refresh'' the data periodically by simply storing it
1344again, in order to make sure other peers can access it.
1345
1346The put API call offers a callback to signal that the PUT request has been
1347sent. This does not guarantee that the data is accessible to others peers,
1348or even that is has been stored, only that the service has requested to
1349a neighboring peer the retransmission of the PUT request towards its final
1350destination. Currently there is no feedback about whether or not the data
1351has been sucessfully stored or where it has been stored. In order to
1352improve the availablilty of the data and to compensate for possible
1353errors, peers leaving and other unfavorable events, just make several
1354PUT requests!
1355
1356@example
1357@verbatiminclude tutorial-examples/019.c
1358@end example
1359
1360@noindent
1361Exercise: Store a value in the DHT periodically to make sure it
1362is available over time. You might consider using the function
1363@code{GNUNET\_SCHEDULER\_add\_delayed} and call
1364@code{GNUNET\_DHT\_put} from inside a helper function.
1365
1366@node Obtaining data from the DHT
1367@subsection Obtaining data from the DHT
1368
1369As we saw in the previous example, the DHT works in an asynchronous mode.
1370Each request to the DHT is executed ``in the background'' and the API
1371calls return immediately. In order to receive results from the DHT, the
1372API provides a callback. Once started, the request runs in the service,
1373the service will try to get as many results as possible (filtering out
1374duplicates) until the timeout expires or we explicitly stop the request.
1375It is possible to give a ``forever'' timeout with
1376@code{GNUNET\_TIME\_UNIT\_FOREVER\_REL}.
1377
1378If we give a route option @code{GNUNET\_DHT\_RO\_RECORD\_ROUTE}
1379the callback will get a list of all the peers the data has travelled,
1380both on the PUT path and on the GET path.
1381
1382@example
1383@verbatiminclude tutorial-examples/020.c
1384@end example
1385
1386@noindent
1387Exercise: Store a value in the DHT and after a while retrieve it.
1388Show the IDs of all the peers the requests have gone through.
1389In order to convert a peer ID to a string, use the function
1390@code{GNUNET\_i2s}. Pay attention to the route option parameters
1391in both calls!
1392
1393@node Implementing a block plugin
1394@subsection Implementing a block plugin
1395
1396In order to store data in the DHT, it is necessary to provide a block
1397plugin. The DHT uses the block plugin to ensure that only well-formed
1398requests and replies are transmitted over the network.
1399
1400The block plugin should be put in a file @file{plugin\_block\_SERVICE.c}
1401in the service's respective directory. The
1402mandatory functions that need to be implemented for a block plugin are
1403described in the following sections.
1404
1405@menu
1406* Validating requests and replies::
1407* Deriving a key from a reply::
1408* Initialization of the plugin::
1409* Shutdown of the plugin::
1410* Integration of the plugin with the build system::
1411@end menu
1412
1413@node Validating requests and replies
1414@subsubsection Validating requests and replies
1415
1416The evaluate function should validate a reply or a request. It returns
1417a @code{GNUNET\_BLOCK\_EvaluationResult}, which is an enumeration. All
1418possible answers are in @file{gnunet\_block\_lib.h}. The function will
1419be called with a @code{reply\_block} argument of @code{NULL} for
1420requests. Note that depending on how @code{evaluate} is called, only
1421some of the possible return values are valid. The specific meaning of
1422the @code{xquery} argument is application-specific. Applications that
1423do not use an extended query should check that the @code{xquery\_size}
1424is zero. The block group is typically used to filter duplicate
1425replies.
1426
1427@example
1428@verbatiminclude tutorial-examples/021.c
1429@end example
1430
1431@noindent
1432Note that it is mandatory to detect duplicate replies in this function
1433and return the respective status code. Duplicate detection is
1434typically done using the Bloom filter block group provided by
1435@file{libgnunetblockgroup.so}. Failure to do so may cause replies to
1436circle in the network.
1437
1438@node Deriving a key from a reply
1439@subsubsection Deriving a key from a reply
1440
1441The DHT can operate more efficiently if it is possible to derive a key
1442from the value of the corresponding block. The @code{get\_key}
1443function is used to obtain the key of a block --- for example, by
1444means of hashing. If deriving the key is not possible, the function
1445should simply return @code{GNUNET\_SYSERR} (the DHT will still work
1446just fine with such blocks).
1447
1448@example
1449@verbatiminclude tutorial-examples/022.c
1450@end example
1451
1452@node Initialization of the plugin
1453@subsubsection Initialization of the plugin
1454
1455The plugin is realized as a shared C library. The library must export
1456an initialization function which should initialize the plugin. The
1457initialization function specifies what block types the plugin cares
1458about and returns a struct with the functions that are to be used for
1459validation and obtaining keys (the ones just defined above).
1460
1461@example
1462@verbatiminclude tutorial-examples/023.c
1463@end example
1464
1465@node Shutdown of the plugin
1466@subsubsection Shutdown of the plugin
1467
1468Following GNUnet's general plugin API concept, the plugin must
1469export a second function for cleaning up. It usually does very
1470little.
1471
1472@example
1473@verbatiminclude tutorial-examples/024.c
1474@end example
1475
1476@node Integration of the plugin with the build system
1477@subsubsection Integration of the plugin with the build system
1478
1479In order to compile the plugin, the @file{Makefile.am} file for the
1480service SERVICE should contain a rule similar to this:
1481@c Actually this is a Makefile not C. But the whole structure of examples
1482@c must be improved.
1483
1484@example
1485@verbatiminclude tutorial-examples/025.Makefile.am
1486@end example
1487
1488@noindent
1489Exercise: Write a block plugin that accepts all queries
1490and all replies but prints information about queries and replies
1491when the respective validation hooks are called.
1492
1493@node Monitoring the DHT
1494@subsection Monitoring the DHT
1495
1496It is possible to monitor the functioning of the local
1497DHT service. When monitoring the DHT, the service will
1498alert the monitoring program of any events, both started
1499locally or received for routing from another peer.
1500The are three different types of events possible: a
1501GET request, a PUT request or a response (a reply to a GET).
1502
1503Since the different events have different associated data,
1504the API gets 3 different callbacks (one for each message type)
1505and optional type and key parameters, to allow for filtering of
1506messages. When an event happens, the appropiate callback is
1507called with all the information about the event.
1508
1509@example
1510@verbatiminclude tutorial-examples/026.c
1511@end example
1512
1513@node Debugging with gnunet-arm
1514@section Debugging with gnunet-arm
1515
1516Even if services are managed by @command{gnunet-arm}, you can
1517start them with @command{gdb} or @command{valgrind}. For
1518example, you could add the following lines to your
1519configuration file to start the DHT service in a @command{gdb}
1520session in a fresh @command{xterm}:
1521
1522@example
1523[dht]
1524PREFIX=xterm -e gdb --args
1525@end example
1526
1527@noindent
1528Alternatively, you can stop a service that was started via
1529ARM and run it manually:
1530
1531@example
1532$ gnunet-arm -k dht
1533$ gdb --args gnunet-service-dht -L DEBUG
1534$ valgrind gnunet-service-dht -L DEBUG
1535@end example
1536
1537@noindent
1538Assuming other services are well-written, they will automatically
1539re-integrate the restarted service with the peer.
1540
1541GNUnet provides a powerful logging mechanism providing log
1542levels @code{ERROR}, @code{WARNING}, @code{INFO} and @code{DEBUG}.
1543The current log level is configured using the @code{$GNUNET_FORCE_LOG}
1544environmental variable. The @code{DEBUG} level is only available if
1545@command{--enable-logging=verbose} was used when running
1546@command{configure}. More details about logging can be found under
1547@uref{https://gnunet.org/logging}.
1548
1549You should also probably enable the creation of core files, by setting
1550@code{ulimit}, and echo'ing @code{1} into
1551@file{/proc/sys/kernel/core\_uses\_pid}. Then you can investigate the
1552core dumps with @command{gdb}, which is often the fastest method to
1553find simple errors.
1554
1555Exercise: Add a memory leak to your service and obtain a trace
1556pointing to the leak using @command{valgrind} while running the service
1557from @command{gnunet-service-arm}.
1558
1559@bye