-re benchmarking and adjusting MAX_QUEUE_PER_PEER
[oweals/gnunet.git] / doc / gnunet-c-tutorial.tex
index 1142630cc7dc4a9e168d300ce0d6d4c12410e8d4..ee24b0ae43082a7e00cad5843a5f9db29591a536 100644 (file)
@@ -146,27 +146,20 @@ to enable verbose logging by adding
 
 \lstset{language=bash}
 \begin{lstlisting}
-$ ./configure --prefix=$HOME --enable-logging
+$ ./configure --prefix=$PREFIX --enable-logging
 $ make
 $ make install
 \end{lstlisting}
 
-After installing GNUnet you have to set the \lstinline|GNUNET_PREFIX|
-environmental variable used by GNUnet to detect it's installation
-directory and add your GNUnet installation to your path environmental
-variable.  This configuration is only valid for the current shell
-session, so you should add \lstinline|export GNUNET_PREFIX=$HOME| to
-your \lstinline|.bash_rc| or \lstinline|.profile| to be sure the
-environment variable is always set. In addition you have to create the
-\lstinline|.gnunet| directory in your home directory where GNUnet
-stores it's data and an empty GNUnet configuration file:
+After installing GNUnet you have to add your GNUnet installation to your path
+environmental variable. In addition you have to create the \lstinline|.gnunet|
+directory in your home directory where GNUnet stores it's data and an empty
+GNUnet configuration file:
 
 \lstset{language=bash}
 \begin{lstlisting}
-$ export GNUNET_PREFIX=$HOME
-$ export PATH=$PATH:$GNUNET_PREFIX/bin
-$ echo export GNUNET_PREFIX=$HOME >> ~/.bashrc
-$ echo export PATH=$GNUNET_PREFIX/bin:$PATH >> ~/.bashrc
+$ export PATH=$PATH:$PREFIX/bin
+$ echo export PATH=$PREFIX/bin:\\$PATH >> ~/.bashrc
 $ mkdir ~/.gnunet/
 $ touch ~/.gnunet/gnunet.conf
 \end{lstlisting}
@@ -179,7 +172,7 @@ binaries and run GNUnet's self check.
 \begin{lstlisting}
 $ which gnunet-arm
 \end{lstlisting}
-should return \lstinline|$GNUNET_PREFIX/bin/gnunet-arm|. It should be
+should return \lstinline|$PREFIX/bin/gnunet-arm|. It should be
 located in your GNUnet installation and the output should not be
 empty. If you see an output like:
 \begin{lstlisting}
@@ -211,7 +204,7 @@ Mar 12 16:57:56-642573 test_program-19449 ERROR Assertion failed at resolver_api
 /bin/bash: line 5: 19449 Aborted                 (core dumped) ${dir}$tst
 FAIL: test_program
 \end{lstlisting}
-double check your {\tt GNUNET\_PREFIX} environmental variable and double check the steps performed in ~\ref{sub:install}
+double check the steps performed in ~\ref{sub:install}
 
 \section{Background: GNUnet Architecture}
 GNUnet is organized in layers and services. Each service is composed of a
@@ -254,7 +247,7 @@ the programmer.
 \section{First Steps with GNUnet}
 
 \subsection{Configure your peer}
-First of all we need to configure your peer. Each peer is started with a configuration containing settings for GNUnet itself and it's services. This configuration is based on the default configuration shipped with GNUnet and can be modified. The default configuration is located in the {\tt \$GNUNET\_PREFIX/share/gnunet/config.d} directory. When starting a peer, you can specify a customized configuration using the the {\tt$-c$} command line switch when starting the ARM service and all other services. When using a modified configuration the default values are loaded and only values specified in the configuration file will replace the default values.
+First of all we need to configure your peer. Each peer is started with a configuration containing settings for GNUnet itself and it's services. This configuration is based on the default configuration shipped with GNUnet and can be modified. The default configuration is located in the {\tt \$PREFIX/share/gnunet/config.d} directory. When starting a peer, you can specify a customized configuration using the the {\tt$-c$} command line switch when starting the ARM service and all other services. When using a modified configuration the default values are loaded and only values specified in the configuration file will replace the default values.
 
 Since we want to start additional peers later, we need
 some modifications from the default configuration. We need to create a separate service home and a file containing our modifications for this peer:
@@ -277,25 +270,29 @@ SERVERS = # prevent bootstrapping
 \subsection{Start a peer}
 Each GNUnet instance (called peer) has an identity (\textit{peer ID}) based on a
 cryptographic public private key pair. The peer ID is the printable hash of the
-public key. So before starting the peer, you may want to just generate the peer's private
-key using the command
+public key.
+
+GNUnet services are controlled by a master service the so called \textit{Automatic Restart Manager} (ARM).
+ARM starts, stops and even restarts services automatically or on demand when a client connects.
+You interact with the ARM service using the \lstinline|gnunet-arm| tool.
+GNUnet can then be started with \lstinline|gnunet-arm -s| and stopped with
+\lstinline|gnunet-arm -e|.  An additional service not automatically started
+can be started using \lstinline|gnunet-arm -i <service name>| and stopped
+using \lstinline|gnunet-arm -k <servicename>|.
+
+Once you have started your peer, you can use many other GNUnet commands
+to interact with it.  For example, you can run:
 \lstset{language=bash}
 \begin{lstlisting}
-$ gnunet-peerinfo -c ~/peer1.conf -s
+$ gnunet-peerinfo -s
 \end{lstlisting}
+to obtain the public key of your peer.
 You should see an output containing the peer ID similar to:
 \lstset{language=bash}
 \begin{lstlisting}
 I am peer `0PA02UVRKQTS2C .. JL5Q78F6H0B1ACPV1CJI59MEQUMQCC5G'.
 \end{lstlisting}
 
-GNUnet services are controlled by a master service the so called \textit{Automatic Restart Manager} (ARM).
-ARM starts, stops and even restarts services automatically or on demand when a client connects.
-You interact with the ARM service using the \lstinline|gnunet-arm| tool.
-GNUnet can then be started with \lstinline|gnunet-arm -s| and stopped with
-\lstinline|gnunet-arm -e|.  An additional service not automatically started
-can be started using \lstinline|gnunet-arm -i <service name>| and stopped
-using \lstinline|gnunet-arm -k <servicename>|.
 
 \subsection{Monitor a peer}
 In this section, we will monitor the behaviour of our peer's DHT service with respect to a
@@ -328,15 +325,15 @@ configuration file to avoid conflicts with ports and directories.
 A peers configuration file is by default located in {\tt ~/.gnunet/gnunet.conf}.
 This file is typically very short or even empty as only the differences to the
 defaults need to be specified.  The defaults are located in
-many files in the {\tt \$GNUNET\_PREFIX/share/gnunet/config.d} directory.
+many files in the {\tt \$PREFIX/share/gnunet/config.d} directory.
 
 To configure the second peer, use the files {\tt
-  \$GNUNET\_PREFIX/share/gnunet/config.d} as a template for your main
+  \$PREFIX/share/gnunet/config.d} as a template for your main
 configuration file:
 %
 \lstset{language=bash}
 \begin{lstlisting}
-$ cat $GNUNET_PREFIX/share/gnunet/config.d/*.conf > peer2.conf
+$ cat $PREFIX/share/gnunet/config.d/*.conf > peer2.conf
 \end{lstlisting}
 Now you have to edit {\tt peer2.conf} and change:
 \begin{itemize}
@@ -409,7 +406,7 @@ by you.
 If you want to use the \texttt{peerinfo} tool to connect your peers, you should:
 \begin{itemize}
 \itemsep0em
- \item{Remove {\tt hostlist} from {\tt DEFAULTSERVICES} (to not connect to the global GNUnet)}
+ \item{Set {\tt FORCESTART = NO} in section {\tt hostlist} (to not connect to the global GNUnet)}
  \item{Start both peers running {\tt gnunet-arm -c peer1.conf -s} and {\tt gnunet-arm -c peer2.conf -s}}
  \item{Get \texttt{HELLO} message of the first peer running {\tt gnunet-peerinfo -c peer1.conf -g}}
  \item{Give the output to the second peer by running {\tt gnunet-peerinfo -c peer2.conf -p '<output>'}}
@@ -515,7 +512,7 @@ obtained as follows:
 $ svn checkout https://gnunet.org/svn/gnunet-ext/
 $ cd gnunet-ext/
 $ ./bootstrap
-$ ./configure --prefix=$HOME --with-gnunet=$GNUNET_PREFIX
+$ ./configure --prefix=$PREFIX --with-gnunet=$PREFIX
 $ make
 $ make install
 $ make check
@@ -985,7 +982,6 @@ in the {\tt gnunet\_server\_lib.h} header.
 \exercise{Change the service respond to the request from your
 client.  Make sure you handle malformed messages in both directions.}
 
-
 \section{Interacting directly with other Peers using the CORE Service}
 
 One of the most important services in GNUnet is the \texttt{CORE} service
@@ -1120,6 +1116,128 @@ disconnects (void *cls,
 
 \exercise{Fix your service to handle peer disconnects.}
 
+\section{Storing peer-specific data using the PEERSTORE service}
+
+GNUnet's PEERSTORE service offers a persistorage for arbitrary peer-specific data.
+Other GNUnet services can use the PEERSTORE to store, retrieve and monitor data records.
+Each data record stored with PEERSTORE contains the following fields:
+
+\begin{itemize}
+\itemsep0em
+  \item subsystem: Name of the subsystem responsible for the record.
+  \item peerid: Identity of the peer this record is related to.
+  \item key: a key string identifying the record.
+  \item value: binary record value.
+  \item expiry: record expiry date.
+\end{itemize}
+
+The first step is to start a connection to the PEERSTORE service:
+\begin{lstlisting}
+#include "gnunet_peerstore_service.h"
+
+peerstore_handle = GNUNET_PEERSTORE_connect (cfg);
+\end{lstlisting}
+The service handle \lstinline|peerstore_handle| will be needed for all subsequent
+PEERSTORE operations.
+
+\subsection{Storing records}
+
+To store a new record, use the following function:
+\begin{lstlisting}
+struct GNUNET_PEERSTORE_StoreContext *
+GNUNET_PEERSTORE_store (struct GNUNET_PEERSTORE_Handle *h,
+                        const char *sub_system,
+                        const struct GNUNET_PeerIdentity *peer,
+                        const char *key,
+                        const void *value,
+                        size_t size,
+                        struct GNUNET_TIME_Absolute expiry,
+                        enum GNUNET_PEERSTORE_StoreOption options,
+                        GNUNET_PEERSTORE_Continuation cont,
+                        void *cont_cls);
+\end{lstlisting}
+
+The \lstinline|options| parameter can either be \lstinline|GNUNET_PEERSTORE_STOREOPTION_MULTIPLE|
+which means that multiple values can be stored under the same key combination (subsystem, peerid, key),
+or \lstinline|GNUNET_PEERSTORE_STOREOPTION_REPLACE| which means that PEERSTORE will replace any
+existing values under the given key combination (subsystem, peerid, key) with the new given value.
+
+The continuation function \lstinline|cont| will be called after the store request is successfully
+sent to the PEERSTORE service. This does not guarantee that the record is successfully stored, only
+that it was received by the service.
+
+The \lstinline|GNUNET_PEERSTORE_store| function returns a handle to the store operation. This handle
+can be used to cancel the store operation only before the continuation function is called:
+\begin{lstlisting}
+void
+GNUNET_PEERSTORE_store_cancel (struct GNUNET_PEERSTORE_StoreContext *sc);
+\end{lstlisting}
+
+\subsection{Retrieving records}
+
+To retrieve stored records, use the following function:
+\begin{lstlisting}
+struct GNUNET_PEERSTORE_IterateContext *
+GNUNET_PEERSTORE_iterate (struct GNUNET_PEERSTORE_Handle *h,
+                          const char *sub_system,
+                          const struct GNUNET_PeerIdentity *peer,
+                          const char *key,
+                          struct GNUNET_TIME_Relative timeout,
+                          GNUNET_PEERSTORE_Processor callback,
+                          void *callback_cls);
+\end{lstlisting}
+The values of \lstinline|peer| and \lstinline|key| can be \lstinline|NULL|. This allows the
+iteration over values stored under any of the following key combinations:
+\begin{itemize}
+\itemsep0em
+  \item (subsystem)
+  \item (subsystem, peerid)
+  \item (subsystem, key)
+  \item (subsystem, peerid, key)
+\end{itemize}
+
+The \lstinline|callback| function will be called once with each retrieved record and once
+more with a \lstinline|NULL| record to signal the end of results.
+
+The \lstinline|GNUNET_PEERSTORE_iterate| function returns a handle to the iterate operation. This
+handle can be used to cancel the iterate operation only before the callback function is called with
+a \lstinline|NULL| record.
+
+\subsection{Monitoring records}
+
+PEERSTORE offers the functionality of monitoring for new records stored under a specific key
+combination (subsystem, peerid, key). To start the monitoring, use the following function:
+\begin{lstlisting}
+struct GNUNET_PEERSTORE_WatchContext *
+GNUNET_PEERSTORE_watch (struct GNUNET_PEERSTORE_Handle *h,
+                        const char *sub_system,
+                        const struct GNUNET_PeerIdentity *peer,
+                        const char *key,
+                        GNUNET_PEERSTORE_Processor callback,
+                        void *callback_cls);
+\end{lstlisting}
+
+Whenever a new record is stored under the given key combination, the \lstinline|callback| function
+will be called with this new record. This will continue until the connection to the PEERSTORE service
+is broken or the watch operation is canceled:
+\begin{lstlisting}
+void
+GNUNET_PEERSTORE_watch_cancel (struct GNUNET_PEERSTORE_WatchContext *wc);
+\end{lstlisting}
+
+\subsection{Disconnecting from PEERSTORE}
+
+When the connection to the PEERSTORE service is no longer needed, disconnect using the following
+function:
+\begin{lstlisting}
+void
+GNUNET_PEERSTORE_disconnect (struct GNUNET_PEERSTORE_Handle *h, int sync_first);
+\end{lstlisting}
+
+If the \lstinline|sync_first| flag is set to \lstinline|GNUNET_YES|, the API will delay the
+disconnection until all store requests are received by the PEERSTORE service. Otherwise,
+it will disconnect immediately.
+
 \section{Using the DHT}
 The DHT allows to store data so other peers in the P2P network can
 access it and retrieve data stored by any peers in the network.