GNUnet  0.19.2
gnunet-service-namecache.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2012, 2013 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your 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  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19  */
20 
27 #include "platform.h"
28 #include "gnunet_util_lib.h"
32 #include "gnunet_signatures.h"
33 #include "namecache.h"
34 
35 #define LOG_STRERROR_FILE(kind, syscall, \
36  filename) GNUNET_log_from_strerror_file (kind, "util", \
37  syscall, \
38  filename)
39 
40 
45 {
50 
55 };
56 
57 
61 static const struct GNUNET_CONFIGURATION_Handle *GSN_cfg;
62 
67 
72 
76 static char *db_lib_name;
77 
78 
84 static void
86 {
88  "Stopping namecache service\n");
89  GNUNET_break (NULL ==
91  GSN_database));
93  db_lib_name = NULL;
94  if (NULL != statistics)
95  {
97  GNUNET_NO);
98  statistics = NULL;
99  }
100 }
101 
102 
111 static void
113  struct GNUNET_SERVICE_Client *client,
114  void *app_ctx)
115 {
116  struct NamecacheClient *nc = app_ctx;
117 
119  "Client %p disconnected\n",
120  client);
121  GNUNET_free (nc);
122 }
123 
124 
133 static void *
134 client_connect_cb (void *cls,
136  struct GNUNET_MQ_Handle *mq)
137 {
138  struct NamecacheClient *nc;
139 
141  "Client %p connected\n",
142  client);
143  nc = GNUNET_new (struct NamecacheClient);
144  nc->client = client;
145  nc->mq = mq;
146  return nc;
147 }
148 
149 
155 {
160 
164  uint32_t request_id;
165 
169  int status;
170 };
171 
172 
179 static void
181  const struct GNUNET_GNSRECORD_Block *block)
182 {
183  struct LookupBlockContext *lnc = cls;
184  struct GNUNET_MQ_Envelope *env;
185  struct LookupBlockResponseMessage *r;
186  size_t bsize;
187 
190  bsize,
192  r->gns_header.r_id = htonl (lnc->request_id);
193  GNUNET_memcpy (&r[1],
194  block,
195  bsize);
197  "blocks found in cache",
198  1,
199  GNUNET_NO);
203  "Sending NAMECACHE_LOOKUP_BLOCK_RESPONSE message\n");
204  GNUNET_MQ_send (lnc->nc->mq,
205  env);
206 }
207 
208 
215 static void
217  const struct LookupBlockMessage *ln_msg)
218 {
219  struct NamecacheClient *nc = cls;
220  struct GNUNET_MQ_Envelope *env;
221  struct LookupBlockContext lnc;
222  struct LookupBlockResponseMessage *zir_end;
223  int ret;
224 
226  "Received NAMECACHE_LOOKUP_BLOCK message\n");
228  "blocks looked up",
229  1,
230  GNUNET_NO);
231  lnc.request_id = ntohl (ln_msg->gns_header.r_id);
232  lnc.nc = nc;
233  lnc.status = GNUNET_OK;
234  if (GNUNET_SYSERR ==
236  &ln_msg->query,
238  &lnc)))
239  {
240  /* internal error (in database plugin); might be best to just hang up on
241  plugin rather than to signal that there are 'no' results, which
242  might also be false... */
243  GNUNET_break (0);
244  GNUNET_SERVICE_client_drop (nc->client);
245  return;
246  }
247  if ((0 == ret) || (GNUNET_SYSERR == lnc.status))
248  {
249  /* no records match at all, generate empty response */
251  "Sending empty NAMECACHE_LOOKUP_BLOCK_RESPONSE message\n");
252  env = GNUNET_MQ_msg (zir_end,
254  zir_end->gns_header.r_id = ln_msg->gns_header.r_id;
255  GNUNET_MQ_send (nc->mq,
256  env);
257  }
259 }
260 
261 
269 static int
270 check_block_cache (void *cls,
271  const struct BlockCacheMessage *rp_msg)
272 {
273  return GNUNET_OK;
274 }
275 
276 
283 static void
285  const struct BlockCacheMessage *rp_msg)
286 {
287  struct NamecacheClient *nc = cls;
288  struct GNUNET_MQ_Envelope *env;
289  struct BlockCacheResponseMessage *rpr_msg;
290  struct GNUNET_GNSRECORD_Block *block;
291  size_t esize;
292  int res;
293 
295  "blocks cached",
296  1,
297  GNUNET_NO);
298  esize = ntohs (rp_msg->gns_header.header.size) - sizeof(struct
300  block = GNUNET_malloc (esize);
301  memcpy (block, &rp_msg[1], esize);
303  "Received NAMECACHE_BLOCK_CACHE message with type %u\n",
304  htonl (block->type));
306  block);
307  GNUNET_free (block);
308  env = GNUNET_MQ_msg (rpr_msg,
310  rpr_msg->gns_header.r_id = rp_msg->gns_header.r_id;
311  rpr_msg->op_result = htonl (res);
312  GNUNET_MQ_send (nc->mq,
313  env);
315 }
316 
317 
325 static void
326 run (void *cls,
327  const struct GNUNET_CONFIGURATION_Handle *cfg,
329 {
330  char *database;
331 
333  "Starting namecache service\n");
334  GSN_cfg = cfg;
335 
336  /* Loading database plugin */
337  if (GNUNET_OK !=
339  "namecache",
340  "database",
341  &database))
343  "No database backend configured\n");
344 
346  "libgnunet_plugin_namecache_%s",
347  database);
349  (void *) GSN_cfg);
350  GNUNET_free (database);
351  if (NULL == GSN_database)
352  {
354  "Could not load database backend `%s'\n",
355  db_lib_name);
357  NULL);
358  return;
359  }
360  statistics = GNUNET_STATISTICS_create ("namecache",
361  cfg);
362 
363  /* Configuring server handles */
365  NULL);
366 }
367 
368 
373  ("namecache",
375  &run,
378  NULL,
379  GNUNET_MQ_hd_fixed_size (lookup_block,
381  struct LookupBlockMessage,
382  NULL),
383  GNUNET_MQ_hd_var_size (block_cache,
385  struct BlockCacheMessage,
386  NULL),
388 
389 
390 /* end of gnunet-service-namecache.c */
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static int res
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
static struct GNUNET_PEERINFO_NotifyContext * nc
Iterator context.
static void handle_lookup_block(void *cls, const struct LookupBlockMessage *ln_msg)
Handles a GNUNET_MESSAGE_TYPE_NAMECACHE_LOOKUP_BLOCK message.
static void handle_block_cache(void *cls, const struct BlockCacheMessage *rp_msg)
Handles a GNUNET_MESSAGE_TYPE_NAMECACHE_BLOCK_CACHE message.
static void cleanup_task(void *cls)
Task run during shutdown.
static struct GNUNET_NAMECACHE_PluginFunctions * GSN_database
Database handle.
static char * db_lib_name
Name of the database plugin.
static void handle_lookup_block_it(void *cls, const struct GNUNET_GNSRECORD_Block *block)
A GNUNET_NAMECACHE_BlockCallback for name lookups in handle_lookup_block.
static struct GNUNET_STATISTICS_Handle * statistics
Handle to the statistics service.
GNUNET_SERVICE_MAIN("namecache", GNUNET_SERVICE_OPTION_NONE, &run, &client_connect_cb, &client_disconnect_cb, NULL, GNUNET_MQ_hd_fixed_size(lookup_block, GNUNET_MESSAGE_TYPE_NAMECACHE_LOOKUP_BLOCK, struct LookupBlockMessage, NULL), GNUNET_MQ_hd_var_size(block_cache, GNUNET_MESSAGE_TYPE_NAMECACHE_BLOCK_CACHE, struct BlockCacheMessage, NULL), GNUNET_MQ_handler_end())
Define "main" method using service macro.
static const struct GNUNET_CONFIGURATION_Handle * GSN_cfg
Configuration handle.
static void * client_connect_cb(void *cls, struct GNUNET_SERVICE_Client *client, struct GNUNET_MQ_Handle *mq)
Add a client to our list of active clients.
static int check_block_cache(void *cls, const struct BlockCacheMessage *rp_msg)
Check a GNUNET_MESSAGE_TYPE_NAMECACHE_BLOCK_CACHE message.
static void client_disconnect_cb(void *cls, struct GNUNET_SERVICE_Client *client, void *app_ctx)
Called whenever a client is disconnected.
static void run(void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_SERVICE_Handle *service)
Process namecache requests.
static unsigned int bsize
Plugin API for the namecache database backend.
API that can be used to store naming information on a GNUnet node.
API to create, modify and access statistics.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
size_t GNUNET_GNSRECORD_block_get_size(const struct GNUNET_GNSRECORD_Block *block)
Returns the length of this block in bytes.
struct GNUNET_TIME_Absolute GNUNET_GNSRECORD_block_get_expiration(const struct GNUNET_GNSRECORD_Block *block)
Returns the expiration of a block.
#define GNUNET_log(kind,...)
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
@ GNUNET_OK
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:304
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct.
Definition: gnunet_mq_lib.h:62
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:77
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
void * GNUNET_PLUGIN_unload(const char *library_name, void *arg)
Unload plugin (runs the "done" callback and returns whatever "done" returned).
Definition: plugin.c:242
void * GNUNET_PLUGIN_load(const char *library_name, void *arg)
Setup plugin (runs the "init" callback and returns whatever "init" returned).
Definition: plugin.c:198
#define GNUNET_MESSAGE_TYPE_NAMECACHE_LOOKUP_BLOCK
Client to service: lookup block.
#define GNUNET_MESSAGE_TYPE_NAMECACHE_BLOCK_CACHE_RESPONSE
Service to client: result of block cache request.
#define GNUNET_MESSAGE_TYPE_NAMECACHE_BLOCK_CACHE
Client to service: cache a block.
#define GNUNET_MESSAGE_TYPE_NAMECACHE_LOOKUP_BLOCK_RESPONSE
Service to client: result of block lookup.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1268
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received,...
Definition: scheduler.c:1303
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2330
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2249
@ GNUNET_SERVICE_OPTION_NONE
Use defaults.
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:638
common internal definitions for namecache service
Cache a record in the namecache.
Definition: namecache.h:95
struct GNUNET_NAMECACHE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMECACHE_BLOCK_CACHE.
Definition: namecache.h:99
Response to a request to cache a block.
Definition: namecache.h:114
int32_t op_result
GNUNET_OK on success, GNUNET_SYSERR error
Definition: namecache.h:123
struct GNUNET_NAMECACHE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMECACHE_BLOCK_CACHE_RESPONSE.
Definition: namecache.h:118
uint32_t type
The zone type (GNUNET_GNSRECORD_TYPE_PKEY)
Handle to a message queue.
Definition: mq.c:87
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
uint32_t r_id
Request ID in NBO.
Definition: namecache.h:51
struct GNUNET_MessageHeader header
header.type will be GNUNET_MESSAGE_TYPE_NAMECACHE_* header.size will be message size
Definition: namecache.h:46
struct returned by the initialization function of the plugin
int(* lookup_block)(void *cls, const struct GNUNET_HashCode *query, GNUNET_NAMECACHE_BlockCallback iter, void *iter_cls)
Get the block for a particular zone and label in the datastore.
int(* cache_block)(void *cls, const struct GNUNET_GNSRECORD_Block *block)
Cache a block in the datastore.
void * cls
Closure to pass to all plugin functions.
struct GNUNET_MQ_Handle * mq
Our connection to the PEERINFO service.
Handle to a client that is connected to a service.
Definition: service.c:252
Handle to a service.
Definition: service.c:118
Handle for the service.
Context for name lookups passed from handle_lookup_block to handle_lookup_block_it as closure.
struct NamecacheClient * nc
The client to send the response to.
uint32_t request_id
Operation id for the name lookup.
Lookup a block in the namecache.
Definition: namecache.h:59
struct GNUNET_NAMECACHE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMECACHE_LOOKUP_BLOCK.
Definition: namecache.h:63
struct GNUNET_HashCode query
The query.
Definition: namecache.h:68
Lookup response.
Definition: namecache.h:76
struct GNUNET_TIME_AbsoluteNBO expire
Expiration time.
Definition: namecache.h:85
struct GNUNET_NAMECACHE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMECACHE_LOOKUP_BLOCK_RESPONSE.
Definition: namecache.h:80
A namecache client.
struct GNUNET_MQ_Handle * mq
The message queue to talk to client.
struct GNUNET_SERVICE_Client * client
The client.