GNUnet  0.17.6
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"
29 #include "gnunet_dnsparser_lib.h"
33 #include "gnunet_signatures.h"
34 #include "namecache.h"
35 
36 #define LOG_STRERROR_FILE(kind, syscall, \
37  filename) GNUNET_log_from_strerror_file (kind, "util", \
38  syscall, \
39  filename)
40 
41 
46 {
51 
56 };
57 
58 
62 static const struct GNUNET_CONFIGURATION_Handle *GSN_cfg;
63 
68 
73 
77 static char *db_lib_name;
78 
79 
85 static void
87 {
89  "Stopping namecache service\n");
90  GNUNET_break (NULL ==
92  GSN_database));
94  db_lib_name = NULL;
95  if (NULL != statistics)
96  {
98  GNUNET_NO);
99  statistics = NULL;
100  }
101 }
102 
103 
112 static void
114  struct GNUNET_SERVICE_Client *client,
115  void *app_ctx)
116 {
117  struct NamecacheClient *nc = app_ctx;
118 
120  "Client %p disconnected\n",
121  client);
122  GNUNET_free (nc);
123 }
124 
125 
134 static void *
135 client_connect_cb (void *cls,
137  struct GNUNET_MQ_Handle *mq)
138 {
139  struct NamecacheClient *nc;
140 
142  "Client %p connected\n",
143  client);
144  nc = GNUNET_new (struct NamecacheClient);
145  nc->client = client;
146  nc->mq = mq;
147  return nc;
148 }
149 
150 
156 {
161 
165  uint32_t request_id;
166 
170  int status;
171 };
172 
173 
180 static void
182  const struct GNUNET_GNSRECORD_Block *block)
183 {
184  struct LookupBlockContext *lnc = cls;
185  struct GNUNET_MQ_Envelope *env;
186  struct LookupBlockResponseMessage *r;
187  size_t bsize;
188 
191  bsize,
193  r->gns_header.r_id = htonl (lnc->request_id);
194  GNUNET_memcpy (&r[1],
195  block,
196  bsize);
198  "blocks found in cache",
199  1,
200  GNUNET_NO);
204  "Sending NAMECACHE_LOOKUP_BLOCK_RESPONSE message\n");
205  GNUNET_MQ_send (lnc->nc->mq,
206  env);
207 }
208 
209 
216 static void
218  const struct LookupBlockMessage *ln_msg)
219 {
220  struct NamecacheClient *nc = cls;
221  struct GNUNET_MQ_Envelope *env;
222  struct LookupBlockContext lnc;
223  struct LookupBlockResponseMessage *zir_end;
224  int ret;
225 
227  "Received NAMECACHE_LOOKUP_BLOCK message\n");
229  "blocks looked up",
230  1,
231  GNUNET_NO);
232  lnc.request_id = ntohl (ln_msg->gns_header.r_id);
233  lnc.nc = nc;
234  lnc.status = GNUNET_OK;
235  if (GNUNET_SYSERR ==
237  &ln_msg->query,
239  &lnc)))
240  {
241  /* internal error (in database plugin); might be best to just hang up on
242  plugin rather than to signal that there are 'no' results, which
243  might also be false... */
244  GNUNET_break (0);
245  GNUNET_SERVICE_client_drop (nc->client);
246  return;
247  }
248  if ((0 == ret) || (GNUNET_SYSERR == lnc.status))
249  {
250  /* no records match at all, generate empty response */
252  "Sending empty NAMECACHE_LOOKUP_BLOCK_RESPONSE message\n");
253  env = GNUNET_MQ_msg (zir_end,
255  zir_end->gns_header.r_id = ln_msg->gns_header.r_id;
256  GNUNET_MQ_send (nc->mq,
257  env);
258  }
260 }
261 
262 
270 static int
271 check_block_cache (void *cls,
272  const struct BlockCacheMessage *rp_msg)
273 {
274  return GNUNET_OK;
275 }
276 
277 
284 static void
286  const struct BlockCacheMessage *rp_msg)
287 {
288  struct NamecacheClient *nc = cls;
289  struct GNUNET_MQ_Envelope *env;
290  struct BlockCacheResponseMessage *rpr_msg;
291  struct GNUNET_GNSRECORD_Block *block;
292  size_t esize;
293  int res;
294 
296  "blocks cached",
297  1,
298  GNUNET_NO);
299  esize = ntohs (rp_msg->gns_header.header.size) - sizeof(struct
301  block = GNUNET_malloc (esize);
302  memcpy (block, &rp_msg[1], esize);
304  "Received NAMECACHE_BLOCK_CACHE message with type %u\n",
305  htonl (block->type));
307  block);
308  GNUNET_free (block);
309  env = GNUNET_MQ_msg (rpr_msg,
311  rpr_msg->gns_header.r_id = rp_msg->gns_header.r_id;
312  rpr_msg->op_result = htonl (res);
313  GNUNET_MQ_send (nc->mq,
314  env);
316 }
317 
318 
326 static void
327 run (void *cls,
328  const struct GNUNET_CONFIGURATION_Handle *cfg,
330 {
331  char *database;
332 
334  "Starting namecache service\n");
335  GSN_cfg = cfg;
336 
337  /* Loading database plugin */
338  if (GNUNET_OK !=
340  "namecache",
341  "database",
342  &database))
344  "No database backend configured\n");
345 
347  "libgnunet_plugin_namecache_%s",
348  database);
350  (void *) GSN_cfg);
351  GNUNET_free (database);
352  if (NULL == GSN_database)
353  {
355  "Could not load database backend `%s'\n",
356  db_lib_name);
358  NULL);
359  return;
360  }
361  statistics = GNUNET_STATISTICS_create ("namecache",
362  cfg);
363 
364  /* Configuring server handles */
366  NULL);
367 }
368 
369 
374  ("namecache",
376  &run,
379  NULL,
380  GNUNET_MQ_hd_fixed_size (lookup_block,
382  struct LookupBlockMessage,
383  NULL),
384  GNUNET_MQ_hd_var_size (block_cache,
386  struct BlockCacheMessage,
387  NULL),
389 
390 
391 /* 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
API for helper library to parse DNS packets.
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
Definition: gnunet_common.h:99
@ GNUNET_NO
Definition: gnunet_common.h:98
@ GNUNET_SYSERR
Definition: gnunet_common.h:97
#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:302
#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:56
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:71
#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:241
void * GNUNET_PLUGIN_load(const char *library_name, void *arg)
Setup plugin (runs the "init" callback and returns whatever "init" returned).
Definition: plugin.c:197
#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:1281
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:1316
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2329
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2248
@ 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:637
common internal definitions for namecache service
Cache a record in the namecache.
Definition: namecache.h:105
struct GNUNET_NAMECACHE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMECACHE_BLOCK_CACHE.
Definition: namecache.h:109
Response to a request to cache a block.
Definition: namecache.h:134
int32_t op_result
GNUNET_OK on success, GNUNET_SYSERR error
Definition: namecache.h:143
struct GNUNET_NAMECACHE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMECACHE_BLOCK_CACHE_RESPONSE.
Definition: namecache.h:138
uint32_t type
The zone type (GNUNET_GNSRECORD_TYPE_PKEY)
Handle to a message queue.
Definition: mq.c:86
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:251
Handle to a service.
Definition: service.c:117
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.