improved log messages
[oweals/gnunet.git] / doc / gnunet-c-tutorial.tex
index 714333672b1d9950369c21b146c48f4d52138771..70981b1387999e24dec334dc9cea341ea7c849bf 100644 (file)
@@ -103,8 +103,25 @@ $ cd gnunet
 $ ./bootstrap
 \end{lstlisting}
 
+The remainder of this tutorial assumes that you have SVN HEAD checked out.
 
 \subsection{Compiling and Installing GNUnet}
+
+First, you need to install the latest {\tt
+  libgnupgerror}\footnote{\url{ftp://ftp.gnupg.org/gcrypt/libgpg-error/libgpg-error-1.11.tar.bz2}}
+and {\tt libgcrypt} version from Git.  The current GNUnet code uses
+ECC functions not available in any released version of libgcrypt.
+
+\lstset{language=bash}
+\begin{lstlisting}
+$ git clone git://git.gnupg.org/libgcrypt.git
+$ cd libgcrypt
+$ ./autogen.sh
+$ ./configure
+$ sudo make install 
+$ sudo ldconfig
+\end{lstlisting}
+
 \label{sub:install}
 Assuming all dependencies are installed, the following commands will compile and install GNUnet in your 
 home directory. You can specify the directory where GNUnet will be installed by changing the \lstinline|--prefix| value when calling \lstinline|./configure|.  If you do not specifiy a prefix, GNUnet is installed in the directory \lstinline|/usr/local|. When developing new applications you may want to enable 
@@ -295,7 +312,10 @@ Now you have to edit {\tt peer2.conf} and change:
 \begin{itemize}
   \itemsep0em
   \item{\texttt{SERVICEHOME} under \texttt{PATHS}}
-  \item{Every value for ``\texttt{PORT}'' (add 10000) in any section (if \texttt{PORT} is enabled, may be disabled using "\#") }
+  \item{Every (uncommented) value for ``\texttt{PORT}'' (add 10000) in any
+        section (the option may be commented out if \texttt{PORT} is 
+        prefixed by "\#", in this case, UNIX domain sockets are used
+        and the PORT option does not need to be touched) }
   \item{Every value for ``\texttt{UNIXPATH}'' in any section (e.g. by adding a "-p2" suffix)}
 \end{itemize}
 to a fresh, unique value.  Make sure that the \texttt{PORT} numbers stay
@@ -375,12 +395,12 @@ Peer `9TVUCS8P5A7ILLBGO6JSTSSN2B44H3D2MUIFJMLKAITC0I22UVFBFP1H8NRK2IA35VKAK16LLO
 GNUnet's testbed service is used for testing scenarios where a number of peers
 are to be started.  The testbed can manage peers on a single host or on multiple
 hosts in a distributed fashion.  On a single affordable computer, it should be
-possible to run around 100 peers without drastically increasing the load on the
+possible to run around tens of peers without drastically increasing the load on the
 system.
 
 The testbed service can be access through its API
 \texttt{include/gnunet\_testbed\_service.h}.  The API provides many routines for
-managing a testbed.  It also provides a helper function
+managing a group of peers.  It also provides a helper function
 \texttt{GNUNET\_TESTBED\_test\_run()} to quickly setup a minimalistic testing
 environment on a single host.
 
@@ -392,116 +412,22 @@ and assigns the ports in configurations only if they are free.
 
 Additionally, the testbed service also reads its options from the same
 configuration file.  Various available options and details about them can be
-found in the testbed default configuration file \texttt{testbed/testbed.conf}.
+found in the testbed default configuration file \texttt{src/testbed/testbed.conf}.
 
 With the testbed API, a sample test case can be structured as follows:
-\lstset{language=c}
+\lstinputlisting[language=C]{testbed_test.c}
+The source code for the above listing can be found at
+\url{https://gnunet.org/svn/gnunet/doc/testbed_test.c}.  After installing GNUnet, the above source code can be compiled as:
+\lstset{language=bash}
 \begin{lstlisting}
-/* Number of peers we want to start */
-#define NUM_PEERS 30
-
-struct GNUNET_TESTBED_Operation *dht_op;
-
-struct GNUNET_DHT_Handle *dht_handle;
-
-struct MyContext
-{
-  int ht_len;
-} ctxt;
-
-static void finish ()                       /* Finish test case */
-{
-  if (NULL != dht_op)
-  {  
-    GNUNET_TESTBED_operation_done (dht_op); /* calls the dht_da() for closing
-                                               down the connection */
-    dht_op = NULL;
-  }
-  result = GNUNET_OK;
-  GNUNET_SCHEDULER_shutdown (); /* Also kills the testbed */
-}
-
-
-static void
-service_connect_comp (void *cls,
-                      struct GNUNET_TESTBED_Operation *op,
-                      void *ca_result,
-                      const char *emsg)
-{
-  /* Service to DHT successful; do something */
-}
-
-
-static void *
-dht_ca (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg)
-{
-  struct MyContext *ctxt = cls;
-
-  /* Use the provided configuration to connect to service */
-  dht_handle = GNUNET_DHT_connect (cfg, ctxt->ht_len);
-  return dht_handle;
-}
-
-
-static void 
-dht_da (void *cls, void *op_result)
-{
-  struct MyContext *ctxt = cls;
-  
-  /* Disconnect from DHT service */  
-  GNUNET_DHT_disconnect ((struct GNUNET_DHT_Handle *) op_result);
-  ctxt->ht_len = 0;
-  dht_handle = NULL;
-}
-
-static void
-test_master (void *cls, unsigned int num_peers,
-             struct GNUNET_TESTBED_Peer **peers)
-{
-  /* Testbed is ready with peers running and connected in a pre-defined overlay
-     topology  */
-
-  /* do something */
-  ctxt.ht_len = 10;
-
-  /* connect to a peers service */
-  dht_op = GNUNET_TESTBED_service_connect 
-      (NULL,                    /* Closure for operation */
-       peers[0],                /* The peer whose service to connect to */
-       "dht"                    /* The name of the service */
-       service_connect_comp,    /* callback to call after a handle to service
-                                   is opened */
-       NULL,                    /* closure for the above callback */
-       dht_ca,                  /* callback to call with peer's configuration;
-                                   this should open the needed service connection */
-       dht_da,                  /* callback to be called when closing the
-                                   opened service connection */
-       &ctxt);                  /* closure for the above two callbacks */
-}
-
-
-int
-main (int argc, char **argv)
-{
-  int ret;
-
-  ret = GNUNET_TESTBED_test_run 
-      ("awesome-test",  /* test case name */
-       "template.conf", /* template configuration */
-       NUM_PEERS,       /* number of peers to start */
-       0LL, /* Event mask - set to 0 for no event notifications */
-       NULL, /* Controller event callback */
-       NULL, /* Closure for controller event callback */
-       &test_master, /* continuation callback to be called when testbed setup is
-                        complete */
-       NULL); /* Closure for the test_master callback */
-  if ( (GNUNET_OK != ret) || (GNUNET_OK != result) )
-    return 1;
-  return 0;
-}
+$ export CPPFLAGS="-I/path/to/gnunet/headers"
+$ export LDFLAGS="-L/path/to/gnunet/libraries"
+$ gcc $CPPFLAGS $LDFLAGS -o testbed-test testbed_test.c  -lgnunettestbed -lgnunetdht -lgnunetutil
 \end{lstlisting}
+The \texttt{CPPFLAGS} and \texttt{LDFLAGS} are necessary if GNUnet is installed
+into a different directory other than \texttt{/usr/local}.
 
-All of testbed API peer management functions treat management actions as
+All of testbed API's peer management functions treat management actions as
 operations and return operation handles.  It is expected that the operations
 begin immediately, but they may get delayed (to balance out load on the system).
 The program using the API then has to take care of marking the operation as
@@ -518,7 +444,7 @@ called.  If the operation is not marked as done in that callback or if the
 callback is given as NULL when creating the operation, the operation completion
 callback will be called.  The API documentation shows which event are to be
 expected in the controller event notifications.  It also documents any
-exceptional behaviours.
+exceptional behaviour.
 
 Once the peers are started, test cases often need to connect some of the peers'
 services.  Normally, opening a connect to a peer's service requires the peer's
@@ -541,8 +467,9 @@ disconnect from the service with the provided service handle (\texttt{op\_result
 
 \exercise{Find out how many peers you can run on your system.}
 
-\exercise{Find out how to create connections from within {\tt run} and create a
-  2D torus topology.  Then use the DHT API to store and retrieve values in the
+\exercise{Find out how to create a 2D torus topology by changing the
+  options in the configuration file.\footnote{See \url{https://gnunet.org/content/supported-topologies}}
+  Then use the DHT API to store and retrieve values in the
   network.}
 
 \section{Developing Applications}
@@ -667,6 +594,8 @@ static int a_flag;
      &GNUNET_GETOPT_set_one, &a_flag},
     GNUNET_GETOPT_OPTION_END
   };
+  string_option = NULL;
+  a_flag = GNUNET_SYSERR;
 // ...
 \end{lstlisting}
 
@@ -675,7 +604,10 @@ the {\tt --help} argument and error handling are taken care of when
 using this approach.  Other {\tt GNUNET\_GETOPT\_}-functions can be used
 to obtain integer value options, increment counters, etc.  You can
 even write custom option parsers for special circumstances not covered
-by the available handlers.
+by the available handlers. To check if an argument was specified by the 
+user you initialize the variable with a specific value (e.g. NULL for 
+a string and GNUNET\_SYSERR for a integer) and check after parsing 
+happened if the values were modified.
 
 Inside the {\tt run} method, the program would perform the
 application-specific logic, which typically involves initializing and
@@ -779,7 +711,7 @@ static size_t
 transmit_cb (void *cls, size_t size, void *buf)
 {
   // ...
-  if (NULL == buf) { handle_error(); return 0; }
+  if (NULL == buf) { /* handle error here */; return 0; }
   GNUNET_assert (size >= msg_size);
   memcpy (buf, my_msg, msg_size);
   // ...