gnunet-ext

Template for writing GNUnet extensions
Log | Files | Refs | README | LICENSE

gnunet-service-ext.c (5114B)


      1 /*
      2      This file is part of GNUnet.
      3      Copyright (C) 20xx GNUnet e.V.
      4 
      5      GNUnet is free software; you can redistribute it and/or modify
      6      it under the terms of the GNU General Public License as published
      7      by the Free Software Foundation; either version 3, or (at your
      8      option) any later version.
      9 
     10      GNUnet is distributed in the hope that it will be useful, but
     11      WITHOUT ANY WARRANTY; without even the implied warranty of
     12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13      General Public License for more details.
     14 
     15      You should have received a copy of the GNU General Public License
     16      along with GNUnet; see the file COPYING.  If not, write to the
     17      Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     18      Boston, MA 02110-1301, USA.
     19 */
     20 
     21 /**
     22  * @file ext/gnunet-service-ext.c
     23  * @brief ext service implementation
     24  * @author Christian Grothoff
     25  */
     26 #include <stddef.h>
     27 
     28 #if HAVE_NETINET_IN_H
     29 #include <netinet/in.h>
     30 #endif
     31 
     32 #include "gnunet_ext_config.h"
     33 #include <gnunet/gnunet_util_lib.h>
     34 #include "gnunet_protocols_ext.h"
     35 
     36 /**
     37  * Some state we track per client.
     38  */
     39 struct ClientContext
     40 {
     41   /**
     42    * For telling service to continue processing more messages.
     43    */
     44   struct GNUNET_SERVICE_Client *c;
     45 
     46   /**
     47    * For sending messages to the client.
     48    */
     49   struct GNUNET_MQ_Handle *mq;
     50 
     51   /**
     52    * Sample state.
     53    */
     54   uint32_t state;
     55 };
     56 
     57 
     58 /**
     59  * Our configuration.
     60  */
     61 static const struct GNUNET_CONFIGURATION_Handle *cfg;
     62 
     63 /**
     64  * This structure holds informations about the project.
     65  */
     66 static const struct GNUNET_OS_ProjectData gnunetext_pd = {
     67   .libname = "libgnunetext",
     68   .project_dirname = "gnunet-ext",
     69   .binary_name = "gnunet-service-ext",
     70   .env_varname = "GNUNET_EXT_PREFIX",
     71   .base_config_varname = "GNUNET_EXT_BASE_CONFIG",
     72   .bug_email = "gnunet-developers@gnu.org",
     73   .homepage = "http://www.gnu.org/s/gnunet/",
     74   .config_file = "gnunet-ext.conf",
     75   .user_config_file = "~/.config/gnunet-ext.conf",
     76   .version = "1.0",
     77   .is_gnu = 1,
     78   .gettext_domain = PACKAGE,
     79   .gettext_path = NULL,
     80   .agpl_url = "https://gnunet.org/git/gnunet-ext.git",
     81 };
     82 
     83 /**
     84  * Initialize the project with the data set in the
     85  * GNUNET_OS_ProjectData structure.  This is defined with
     86  * __attribute__ ((constructor)) because it has to be called before
     87  * the main function (implicitly defined by GNUNET_SERVICE_MAIN.)
     88  * Other "pre-main" initialization can be performed here too.
     89  */
     90 static void __attribute__ ((constructor))
     91 project_data_initialize (void)
     92 {
     93   GNUNET_OS_init (&gnunetext_pd);
     94 }
     95 
     96 
     97 /**
     98  * Handle EXT-message.
     99  *
    100  * @param cls identification of the client
    101  * @param message the actual message
    102  */
    103 static void
    104 handle_ext (void *cls,
    105             const struct GNUNET_MessageHeader *message)
    106 {
    107   struct ClientContext *cc = cls;
    108   struct GNUNET_MQ_Envelope *env;
    109   struct GNUNET_MessageHeader *response;
    110 
    111   /* Send same type of message back... */
    112   env = GNUNET_MQ_msg (response,
    113                        GNUNET_MESSAGE_TYPE_EXT);
    114   GNUNET_MQ_send (cc->mq,
    115                   env);
    116 
    117   /* Continue processing more messages from client */
    118   GNUNET_SERVICE_client_continue (cc->c);
    119 }
    120 
    121 
    122 /**
    123  * Task run during shutdown.
    124  *
    125  * @param cls unused
    126  */
    127 static void
    128 shutdown_task (void *cls)
    129 {
    130   /* Clean up whatever #run() setup here. */
    131 }
    132 
    133 
    134 /**
    135  * Process statistics requests.
    136  *
    137  * @param cls closure
    138  * @param server the initialized server
    139  * @param c configuration to use
    140  */
    141 static void
    142 run (void *cls,
    143      const struct GNUNET_CONFIGURATION_Handle *c,
    144      struct GNUNET_SERVICE_Handle *service)
    145 {
    146   cfg = c;
    147   GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
    148                                  NULL);
    149 }
    150 
    151 
    152 /**
    153  * Callback called when a client connects to the service.
    154  *
    155  * @param cls closure for the service
    156  * @param c the new client that connected to the service
    157  * @param mq the message queue used to send messages to the client
    158  * @return @a c
    159  */
    160 static void *
    161 client_connect_cb (void *cls,
    162                    struct GNUNET_SERVICE_Client *c,
    163                    struct GNUNET_MQ_Handle *mq)
    164 {
    165   struct ClientContext *cc;
    166 
    167   cc = GNUNET_new (struct ClientContext);
    168   cc->c = c;
    169   cc->mq = mq;
    170   /* setup more for new client here */
    171   return cc;
    172 }
    173 
    174 
    175 /**
    176  * Callback called when a client disconnected from the service
    177  *
    178  * @param cls closure for the service
    179  * @param c the client that disconnected
    180  * @param internal_cls our `struct ClientContext`
    181  */
    182 static void
    183 client_disconnect_cb (void *cls,
    184                       struct GNUNET_SERVICE_Client *c,
    185                       void *internal_cls)
    186 {
    187   struct ClientContext *cc = internal_cls;
    188 
    189   GNUNET_assert (cc->c == c);
    190   /* Tear down rest of client here */
    191   GNUNET_free (cc);
    192 }
    193 
    194 
    195 /**
    196  * Define "main" method using service macro.
    197  */
    198 GNUNET_SERVICE_MAIN
    199   ("ext",
    200   GNUNET_SERVICE_OPTION_NONE,
    201   &run,
    202   &client_connect_cb,
    203   &client_disconnect_cb,
    204   NULL,
    205   GNUNET_MQ_hd_fixed_size (ext,
    206                            GNUNET_MESSAGE_TYPE_EXT,
    207                            struct GNUNET_MessageHeader,
    208                            NULL),
    209   GNUNET_MQ_handler_end ());
    210 
    211 /* end of gnunet-service-ext.c */