2 This file is part of GNUnet.
3 (C) 2009 Christian Grothoff (and other contributing authors)
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.
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.
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., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
22 * @file namestore/gnunet-service-namestore.c
23 * @brief namestore for the GNUnet naming system
24 * @author Matthias Wachs
27 #include "gnunet_getopt_lib.h"
28 #include "gnunet_service_lib.h"
29 #include "gnunet_namestore_service.h"
30 #include "gnunet_namestore_plugin.h"
31 #include "namestore.h"
36 * A namestore operation.
38 struct GNUNET_NAMESTORE_Operation
40 struct GNUNET_NAMESTORE_Operation *next;
41 struct GNUNET_NAMESTORE_Operation *prev;
45 char *data; /*stub data pointer*/
52 struct GNUNET_NAMESTORE_Client
54 struct GNUNET_NAMESTORE_Client *next;
55 struct GNUNET_NAMESTORE_Client *prev;
57 struct GNUNET_SERVER_Client * client;
59 struct GNUNET_NAMESTORE_Operation *op_head;
60 struct GNUNET_NAMESTORE_Operation *op_tail;
66 * Configuration handle.
68 const struct GNUNET_CONFIGURATION_Handle *GSN_cfg;
70 static struct GNUNET_NAMESTORE_PluginFunctions *GSN_database;
73 * Our notification context.
75 static struct GNUNET_SERVER_NotificationContext *snc;
77 static char *db_lib_name;
79 static struct GNUNET_NAMESTORE_Client *client_head;
80 static struct GNUNET_NAMESTORE_Client *client_tail;
84 * Task run during shutdown.
90 cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
92 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping namestore service\n");
94 struct GNUNET_NAMESTORE_Operation * no;
95 struct GNUNET_NAMESTORE_Client * nc;
97 for (nc = client_head; nc != NULL; nc = nc->next)
99 for (no = nc->op_head; no != NULL; no = no->next)
101 GNUNET_CONTAINER_DLL_remove (nc->op_head, nc->op_tail, no);
106 GNUNET_CONTAINER_DLL_remove (client_head, client_tail, nc);
109 GNUNET_SERVER_notification_context_destroy (snc);
112 GNUNET_break (NULL == GNUNET_PLUGIN_unload (db_lib_name, GSN_database));
113 GNUNET_free (db_lib_name);
116 static struct GNUNET_NAMESTORE_Client *
117 client_lookup (struct GNUNET_SERVER_Client *client)
119 struct GNUNET_NAMESTORE_Client * nc;
121 GNUNET_assert (NULL != client);
123 for (nc = client_head; nc != NULL; nc = nc->next)
125 if (client == nc->client)
133 * Called whenever a client is disconnected. Frees our
134 * resources associated with that client.
137 * @param client identification of the client
140 client_disconnect_notification (void *cls, struct GNUNET_SERVER_Client *client)
142 struct GNUNET_NAMESTORE_Operation * no;
143 struct GNUNET_NAMESTORE_Client * nc;
147 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p disconnected \n", client);
149 nc = client_lookup (client);
151 if ((NULL == client) || (NULL == nc))
154 for (no = nc->op_head; no != NULL; no = no->next)
156 GNUNET_CONTAINER_DLL_remove (nc->op_head, nc->op_tail, no);
160 GNUNET_CONTAINER_DLL_remove (client_head, client_tail, nc);
164 static void handle_start (void *cls,
165 struct GNUNET_SERVER_Client * client,
166 const struct GNUNET_MessageHeader * message)
168 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p connected\n", client);
170 struct GNUNET_NAMESTORE_Client * nc = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_Client));
172 GNUNET_SERVER_notification_context_add (snc, client);
173 GNUNET_CONTAINER_DLL_insert(client_head, client_tail, nc);
175 GNUNET_SERVER_receive_done (client, GNUNET_OK);
178 static void handle_lookup_name (void *cls,
179 struct GNUNET_SERVER_Client * client,
180 const struct GNUNET_MessageHeader * message)
182 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "NAMESTORE_LOOKUP_NAME");
184 struct GNUNET_NAMESTORE_Client *nc;
188 nc = client_lookup(client);
192 GNUNET_SERVER_receive_done (client, GNUNET_OK);
196 struct LookupNameMessage * ln_msg = (struct LookupNameMessage *) message;
197 id = ntohl (ln_msg->op_id);
199 /* do the actual lookup */
202 struct LookupNameResponseMessage lnr_msg;
203 r_size = sizeof (struct LookupNameResponseMessage);
205 lnr_msg.header.type = ntohs (GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME_RESPONSE);
206 lnr_msg.header.size = ntohs (r_size);
207 lnr_msg.op_id = htonl (id);
209 GNUNET_SERVER_notification_context_unicast (snc, nc->client, (const struct GNUNET_MessageHeader *) &lnr_msg, GNUNET_NO);
210 GNUNET_SERVER_receive_done (client, GNUNET_OK);
215 * Process template requests.
218 * @param server the initialized server
219 * @param cfg configuration to use
222 run (void *cls, struct GNUNET_SERVER_Handle *server,
223 const struct GNUNET_CONFIGURATION_Handle *cfg)
227 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting namestore service\n");
229 static const struct GNUNET_SERVER_MessageHandler handlers[] = {
230 {&handle_start, NULL,
231 GNUNET_MESSAGE_TYPE_NAMESTORE_START, sizeof (struct StartMessage)},
232 {&handle_lookup_name, NULL,
233 GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME, sizeof (struct LookupNameMessage)},
239 /* Loading database plugin */
241 GNUNET_CONFIGURATION_get_value_string (cfg, "namestore", "database",
243 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No database backend configured\n");
245 GNUNET_asprintf (&db_lib_name, "libgnunet_plugin_namestore_%s", database);
246 GSN_database = GNUNET_PLUGIN_load (db_lib_name, (void *) GSN_cfg);
247 if (GSN_database == NULL)
248 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not load database backend `%s'\n",
250 GNUNET_free (database);
252 /* Configuring server handles */
253 GNUNET_SERVER_add_handlers (server, handlers);
254 snc = GNUNET_SERVER_notification_context_create (server, 16);
255 GNUNET_SERVER_disconnect_notify (server,
256 &client_disconnect_notification,
259 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup_task,
266 * The main function for the template service.
268 * @param argc number of arguments from the command line
269 * @param argv command line arguments
270 * @return 0 ok, 1 on error
273 main (int argc, char *const *argv)
276 GNUNET_SERVICE_run (argc, argv, "namestore",
277 GNUNET_SERVICE_OPTION_NONE, &run, NULL)) ? 0 : 1;
280 /* end of gnunet-service-namestore.c */