GNUnet  0.17.6
namecache_api.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2010-2013, 2016 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 
29 #include "platform.h"
30 #include "gnunet_util_lib.h"
31 #include "gnunet_crypto_lib.h"
32 #include "gnunet_constants.h"
33 #include "gnunet_dnsparser_lib.h"
34 #include "gnunet_gnsrecord_lib.h"
35 #include "gnunet_signatures.h"
37 #include "namecache.h"
38 
39 
40 #define LOG(kind, ...) GNUNET_log_from (kind, "namecache-api", __VA_ARGS__)
41 
42 
48 {
53 
58 
63 
68 
72  void *cont_cls;
73 
78 
83 
87  uint32_t op_id;
88 };
89 
90 
95 {
100 
105 
109  struct GNUNET_CLIENT_TransmitHandle *th;
110 
115 
120 
125 
130 
135 
139  uint32_t last_op_id_used;
140 };
141 
142 
148 static void
150 
151 
159 static struct GNUNET_NAMECACHE_QueueEntry *
161  uint32_t rid)
162 {
164 
165  for (qe = h->op_head; qe != NULL; qe = qe->next)
166  {
167  if (qe->op_id == rid)
168  {
169  GNUNET_CONTAINER_DLL_remove (h->op_head,
170  h->op_tail,
171  qe);
172  return qe;
173  }
174  }
175  return NULL;
176 }
177 
178 
186 static int
188  const struct LookupBlockResponseMessage *msg)
189 {
190  /* any length will do, format validation is in handler */
191  return GNUNET_OK;
192 }
193 
194 
202 static void
204  const struct LookupBlockResponseMessage *msg)
205 {
206  struct GNUNET_NAMECACHE_Handle *h = cls;
207  size_t size;
209 
211  "Received LOOKUP_BLOCK_RESPONSE\n");
212  qe = find_qe (h,
213  ntohl (msg->gns_header.r_id));
214  if (NULL == qe)
215  return;
216  if (0 == GNUNET_TIME_absolute_ntoh (msg->expire).abs_value_us)
217  {
218  /* no match found */
219  if (NULL != qe->block_proc)
220  qe->block_proc (qe->block_proc_cls,
221  NULL);
222  GNUNET_free (qe);
223  return;
224  }
225  size = ntohs (msg->gns_header.header.size)
226  - sizeof(struct LookupBlockResponseMessage);
227  {
228  char buf[size] GNUNET_ALIGN;
229  struct GNUNET_GNSRECORD_Block *block;
230 
231  memset (buf, 0, size);
232  block = (struct GNUNET_GNSRECORD_Block *) buf;
233  GNUNET_memcpy (block,
234  &msg[1],
235  size);
236  if (GNUNET_OK !=
238  {
239  GNUNET_break (0);
240  if (NULL != qe->block_proc)
241  qe->block_proc (qe->block_proc_cls,
242  NULL);
243  force_reconnect (h);
244  }
245  else
246  {
247  if (NULL != qe->block_proc)
248  qe->block_proc (qe->block_proc_cls,
249  block);
250  }
251  }
252  GNUNET_free (qe);
253 }
254 
255 
265 static void
267  const struct BlockCacheResponseMessage *msg)
268 {
269  struct GNUNET_NAMECACHE_Handle *h = cls;
271  int res;
272 
274  "Received BLOCK_CACHE_RESPONSE\n");
275  qe = find_qe (h,
276  ntohl (msg->gns_header.r_id));
277  if (NULL == qe)
278  return;
279  res = ntohl (msg->op_result);
280  /* TODO: add actual error message from namecache to response... */
281  if (NULL != qe->cont)
282  qe->cont (qe->cont_cls,
283  res,
284  (GNUNET_OK == res)
285  ? NULL
286  : _ ("Namecache failed to cache block"));
287  GNUNET_free (qe);
288 }
289 
290 
299 static void
300 mq_error_handler (void *cls,
301  enum GNUNET_MQ_Error error)
302 {
303  struct GNUNET_NAMECACHE_Handle *h = cls;
304 
305  force_reconnect (h);
306 }
307 
308 
314 static void
316 {
318  GNUNET_MQ_hd_var_size (lookup_block_response,
321  h),
322  GNUNET_MQ_hd_fixed_size (block_cache_response,
325  h),
327  };
328 
329  GNUNET_assert (NULL == h->mq);
331  "namecache",
332  handlers,
334  h);
335 }
336 
337 
343 static void
345 {
346  struct GNUNET_NAMECACHE_Handle *h = cls;
347 
348  h->reconnect_task = NULL;
349  reconnect (h);
350 }
351 
352 
358 static void
360 {
362 
363  h->reconnect = GNUNET_NO;
365  h->mq = NULL;
366  while (NULL != (qe = h->op_head))
367  {
368  GNUNET_CONTAINER_DLL_remove (h->op_head,
369  h->op_tail,
370  qe);
371  if (NULL != qe->cont)
372  qe->cont (qe->cont_cls,
374  _ ("Error communicating with namecache service"));
375  GNUNET_free (qe);
376  }
378  "Reconnecting to namecache\n");
379  h->reconnect_delay = GNUNET_TIME_STD_BACKOFF (h->reconnect_delay);
380  h->reconnect_task = GNUNET_SCHEDULER_add_delayed (h->reconnect_delay,
382  h);
383 }
384 
385 
392 static uint32_t
394 {
395  return h->last_op_id_used++;
396 }
397 
398 
407 {
408  struct GNUNET_NAMECACHE_Handle *h;
409 
411  h->cfg = cfg;
412  reconnect (h);
413  if (NULL == h->mq)
414  {
415  GNUNET_free (h);
416  return NULL;
417  }
418  return h;
419 }
420 
421 
428 void
430 {
432 
433  GNUNET_break (NULL == h->op_head);
434  while (NULL != (q = h->op_head))
435  {
436  GNUNET_CONTAINER_DLL_remove (h->op_head,
437  h->op_tail,
438  q);
439  GNUNET_free (q);
440  }
441  if (NULL != h->mq)
442  {
444  h->mq = NULL;
445  }
446  if (NULL != h->reconnect_task)
447  {
449  h->reconnect_task = NULL;
450  }
451  GNUNET_free (h);
452 }
453 
454 
467  const struct GNUNET_GNSRECORD_Block *block,
469  void *cont_cls)
470 {
472  struct BlockCacheMessage *msg;
473  struct GNUNET_MQ_Envelope *env;
474  uint32_t rid;
475  size_t blen;
476 
477  if (NULL == h->mq)
478  return NULL;
479  blen = GNUNET_GNSRECORD_block_get_size (block);
480  rid = get_op_id (h);
482  qe->nsh = h;
483  qe->cont = cont;
484  qe->cont_cls = cont_cls;
485  qe->op_id = rid;
487  h->op_tail,
488  qe);
489  /* send msg */
491  blen,
493  msg->gns_header.r_id = htonl (rid);
494  GNUNET_memcpy (&msg[1],
495  block,
496  blen);
497  GNUNET_MQ_send (h->mq,
498  env);
499  return qe;
500 }
501 
502 
516  const struct GNUNET_HashCode *derived_hash,
518  void *proc_cls)
519 {
521  struct LookupBlockMessage *msg;
522  struct GNUNET_MQ_Envelope *env;
523  uint32_t rid;
524 
525  if (NULL == h->mq)
526  return NULL;
528  "Looking for block under %s\n",
529  GNUNET_h2s (derived_hash));
530  rid = get_op_id (h);
532  qe->nsh = h;
533  qe->block_proc = proc;
534  qe->block_proc_cls = proc_cls;
535  qe->op_id = rid;
537  h->op_tail,
538  qe);
539  env = GNUNET_MQ_msg (msg,
541  msg->gns_header.r_id = htonl (rid);
542  msg->query = *derived_hash;
543  GNUNET_MQ_send (h->mq,
544  env);
545  return qe;
546 }
547 
548 
555 void
557 {
558  struct GNUNET_NAMECACHE_Handle *h = qe->nsh;
559 
560  GNUNET_CONTAINER_DLL_remove (h->op_head,
561  h->op_tail,
562  qe);
563  GNUNET_free (qe);
564 }
565 
566 
567 /* end of namecache_api.c */
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
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 struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:99
static int res
static struct GNUNET_CADET_MessageHandler handlers[]
Handlers, for diverse services.
static struct GNUNET_DATASTORE_QueueEntry * qe
Current operation.
static struct GNUNET_REVOCATION_Query * q
Handle for revocation query.
static char buf[2048]
cryptographic primitives for GNUnet
API for helper library to parse DNS packets.
API that can be used to manipulate GNS record data.
API that can be used to store naming information on a GNUnet node.
struct GNUNET_MQ_Handle * GNUNET_CLIENT_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *service_name, const struct GNUNET_MQ_MessageHandler *handlers, GNUNET_MQ_ErrorHandler error_handler, void *error_handler_cls)
Create a message queue to connect to a GNUnet service.
Definition: client.c:1055
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_block_verify(const struct GNUNET_GNSRECORD_Block *block)
Check if a signature is valid.
size_t GNUNET_GNSRECORD_block_get_size(const struct GNUNET_GNSRECORD_Block *block)
Returns the length of this block in bytes.
#define GNUNET_log(kind,...)
void * cls
Closure for mv and cb.
#define GNUNET_ALIGN
gcc-ism to force alignment; we use this to align char-arrays that may then be cast to 'struct's.
#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_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
GNUNET_MQ_Error
Error codes for the queue.
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_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition: mq.c:685
void(* GNUNET_NAMECACHE_ContinuationWithStatus)(void *cls, int32_t success, const char *emsg)
Continuation called to notify client about result of the operation.
void GNUNET_NAMECACHE_disconnect(struct GNUNET_NAMECACHE_Handle *h)
Disconnect from the namecache service (and free associated resources).
void GNUNET_NAMECACHE_cancel(struct GNUNET_NAMECACHE_QueueEntry *qe)
Cancel a namecache operation.
void(* GNUNET_NAMECACHE_BlockProcessor)(void *cls, const struct GNUNET_GNSRECORD_Block *block)
Process a record that was stored in the namecache.
struct GNUNET_NAMECACHE_Handle * GNUNET_NAMECACHE_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Initialize the connection with the NAMECACHE service.
struct GNUNET_NAMECACHE_QueueEntry * GNUNET_NAMECACHE_lookup_block(struct GNUNET_NAMECACHE_Handle *h, const struct GNUNET_HashCode *derived_hash, GNUNET_NAMECACHE_BlockProcessor proc, void *proc_cls)
Get a result for a particular key from the namecache.
struct GNUNET_NAMECACHE_QueueEntry * GNUNET_NAMECACHE_block_cache(struct GNUNET_NAMECACHE_Handle *h, const struct GNUNET_GNSRECORD_Block *block, GNUNET_NAMECACHE_ContinuationWithStatus cont, void *cont_cls)
Store an item in the namecache.
#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.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:957
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1254
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:736
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
common internal definitions for namecache service
static uint32_t get_op_id(struct GNUNET_NAMECACHE_Handle *h)
Get a fresh operation id to distinguish between namecache requests.
static void handle_lookup_block_response(void *cls, const struct LookupBlockResponseMessage *msg)
Handle an incoming message of type GNUNET_MESSAGE_TYPE_NAMECACHE_LOOKUP_BLOCK_RESPONSE.
static void reconnect(struct GNUNET_NAMECACHE_Handle *h)
Reconnect to namecache service.
static int check_lookup_block_response(void *cls, const struct LookupBlockResponseMessage *msg)
Handle an incoming message of type GNUNET_MESSAGE_TYPE_NAMECACHE_LOOKUP_BLOCK_RESPONSE.
static struct GNUNET_NAMECACHE_QueueEntry * find_qe(struct GNUNET_NAMECACHE_Handle *h, uint32_t rid)
Find queue entry for the given rid.
static void mq_error_handler(void *cls, enum GNUNET_MQ_Error error)
Generic error handler, called with the appropriate error code and the same closure specified at the c...
static void force_reconnect(struct GNUNET_NAMECACHE_Handle *h)
Disconnect from service and then reconnect.
#define LOG(kind,...)
Definition: namecache_api.c:40
static void handle_block_cache_response(void *cls, const struct BlockCacheResponseMessage *msg)
Handle an incoming message of type GNUNET_MESSAGE_TYPE_NAMECACHE_BLOCK_CACHE_RESPONSE.
static void reconnect_task(void *cls)
Re-establish the connection to the service.
static unsigned int size
Size of the "table".
Definition: peer.c:67
#define _(String)
GNU gettext support macro.
Definition: platform.h:177
Cache a record in the namecache.
Definition: namecache.h:105
Response to a request to cache a block.
Definition: namecache.h:134
struct GNUNET_MQ_Handle * mq
Our connection to the ARM service.
Definition: arm_api.c:107
const struct GNUNET_CONFIGURATION_Handle * cfg
The configuration that we are using.
Definition: arm_api.c:112
struct GNUNET_SCHEDULER_Task * reconnect_task
ID of the reconnect task (if any).
Definition: arm_api.c:147
struct GNUNET_DATASTORE_QueueEntry * next
This is a linked list.
GNUNET_DATASTORE_ContinuationWithStatus cont
Function to call after transmission of the request.
void * cont_cls
Closure for cont.
A 512-bit hashcode.
Handle to a message queue.
Definition: mq.c:86
Message handler for a specific message type.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
Connection to the NAMECACHE service.
Definition: namecache_api.c:95
struct GNUNET_CLIENT_TransmitHandle * th
Currently pending transmission request (or NULL).
struct GNUNET_TIME_Relative reconnect_delay
Delay introduced before we reconnect.
struct GNUNET_MQ_Handle * mq
Message queue to service.
const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration to use.
Definition: namecache_api.c:99
uint32_t last_op_id_used
The last operation id used for a NAMECACHE operation.
struct GNUNET_NAMECACHE_QueueEntry * op_head
Head of pending namecache queue entries.
int reconnect
Should we reconnect to service due to some serious error?
struct GNUNET_SCHEDULER_Task * reconnect_task
Reconnect task.
struct GNUNET_NAMECACHE_QueueEntry * op_tail
Tail of pending namecache queue entries.
An QueueEntry used to store information for a pending NAMECACHE record operation.
Definition: namecache_api.c:48
struct GNUNET_NAMECACHE_QueueEntry * prev
Kept in a DLL.
Definition: namecache_api.c:57
void * cont_cls
Closure for cont.
Definition: namecache_api.c:72
struct GNUNET_NAMECACHE_QueueEntry * next
Kept in a DLL.
Definition: namecache_api.c:52
GNUNET_NAMECACHE_ContinuationWithStatus cont
Continuation to call.
Definition: namecache_api.c:67
GNUNET_NAMECACHE_BlockProcessor block_proc
Function to call with the blocks we get back; or NULL.
Definition: namecache_api.c:77
struct GNUNET_NAMECACHE_Handle * nsh
Main handle to access the namecache.
Definition: namecache_api.c:62
uint32_t op_id
The operation id this zone iteration operation has.
Definition: namecache_api.c:87
void * block_proc_cls
Closure for block_proc.
Definition: namecache_api.c:82
Entry in list of pending tasks.
Definition: scheduler.c:135
uint64_t abs_value_us
The actual value.
Time for relative time used by GNUnet, in microseconds.
Lookup a block in the namecache.
Definition: namecache.h:59
Lookup response.
Definition: namecache.h:76