GNUnet  0.11.x
gns_api.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2009-2013, 2016, 2018 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  */
26 #include "platform.h"
27 #include "gnunet_util_lib.h"
28 #include "gnunet_constants.h"
29 #include "gnunet_arm_service.h"
30 #include "gnunet_hello_lib.h"
31 #include "gnunet_protocols.h"
32 #include "gnunet_dht_service.h"
33 #include "gns.h"
34 #include "gns_api.h"
35 
36 
37 #define LOG(kind, ...) GNUNET_log_from (kind, "gns-api", __VA_ARGS__)
38 
43 {
48 
53 
58 
63 
67  void *proc_cls;
68 
73 
77  uint32_t r_id;
78 };
79 
80 
86 static void
88 
89 
95 static void
96 reconnect_task (void *cls)
97 {
98  struct GNUNET_GNS_Handle *handle = cls;
99 
100  handle->reconnect_task = NULL;
101  reconnect (handle);
102 }
103 
104 
110 static void
112 {
113  GNUNET_MQ_destroy (handle->mq);
114  handle->mq = NULL;
115  handle->reconnect_backoff
117  handle->reconnect_task
120  handle);
121 }
122 
123 
132 static void
133 mq_error_handler (void *cls,
134  enum GNUNET_MQ_Error error)
135 {
136  struct GNUNET_GNS_Handle *handle = cls;
137 
139  "Problem with message queue. error: %i\n",
140  error);
141  force_reconnect (handle);
142 }
143 
144 
151 static int
152 check_result (void *cls,
153  const struct LookupResultMessage *lookup_msg)
154 {
155  size_t mlen = ntohs (lookup_msg->header.size) - sizeof(*lookup_msg);
156  uint32_t rd_count = ntohl (lookup_msg->rd_count);
157  struct GNUNET_GNSRECORD_Data rd[rd_count];
158 
159  (void) cls;
160  if (GNUNET_SYSERR ==
162  (const char*) &lookup_msg[1],
163  rd_count,
164  rd))
165  {
166  GNUNET_break (0);
167  return GNUNET_SYSERR;
168  }
169  return GNUNET_OK;
170 }
171 
172 
179 static void
180 handle_result (void *cls,
181  const struct LookupResultMessage *lookup_msg)
182 {
183  struct GNUNET_GNS_Handle *handle = cls;
184  size_t mlen = ntohs (lookup_msg->header.size) - sizeof(*lookup_msg);
185  uint32_t rd_count = ntohl (lookup_msg->rd_count);
186  struct GNUNET_GNSRECORD_Data rd[rd_count];
187  uint32_t r_id = ntohl (lookup_msg->id);
190  void *proc_cls;
191 
193  "Received lookup reply from GNS service (%u records)\n",
194  (unsigned int) rd_count);
195  for (lr = handle->lookup_head; NULL != lr; lr = lr->next)
196  if (lr->r_id == r_id)
197  break;
198  if (NULL == lr)
199  return;
200  proc = lr->lookup_proc;
201  proc_cls = lr->proc_cls;
202 
205  (const
206  char*) &lookup_msg[1],
207  rd_count,
208  rd));
209  proc (proc_cls,
210  rd_count,
211  rd);
213  handle->lookup_tail,
214  lr);
215  if (NULL != lr->env)
216  GNUNET_MQ_discard (lr->env);
217  GNUNET_free (lr);
218 }
219 
220 
226 static void
228 {
229  struct GNUNET_MQ_MessageHandler handlers[] = {
232  struct LookupResultMessage,
233  handle),
235  };
236 
237  GNUNET_assert (NULL == handle->mq);
239  "Trying to connect to GNS\n");
240  handle->mq = GNUNET_CLIENT_connect (handle->cfg,
241  "gns",
242  handlers,
244  handle);
245  if (NULL == handle->mq)
246  return;
247  for (struct GNUNET_GNS_LookupRequest *lh = handle->lookup_head;
248  NULL != lh;
249  lh = lh->next)
250  GNUNET_MQ_send_copy (handle->mq,
251  lh->env);
252 }
253 
254 
261 struct GNUNET_GNS_Handle *
263 {
264  struct GNUNET_GNS_Handle *handle;
265 
266  handle = GNUNET_new (struct GNUNET_GNS_Handle);
267  handle->cfg = cfg;
268  reconnect (handle);
269  if (NULL == handle->mq)
270  {
271  GNUNET_free (handle);
272  return NULL;
273  }
274  return handle;
275 }
276 
277 
283 void
285 {
286  if (NULL != handle->mq)
287  {
288  GNUNET_MQ_destroy (handle->mq);
289  handle->mq = NULL;
290  }
291  if (NULL != handle->reconnect_task)
292  {
294  handle->reconnect_task = NULL;
295  }
296  GNUNET_assert (NULL == handle->lookup_head);
297  GNUNET_free (handle);
298 }
299 
300 
307 void *
309 {
310  struct GNUNET_GNS_Handle *handle = lr->gns_handle;
311  void *ret;
312 
314  handle->lookup_tail,
315  lr);
316  GNUNET_MQ_discard (lr->env);
317  ret = lr->proc_cls;
318  GNUNET_free (lr);
319  return ret;
320 }
321 
322 
337  const char *name,
338  const struct GNUNET_CRYPTO_EcdsaPublicKey *zone,
339  uint32_t type,
342  void *proc_cls)
343 {
344  /* IPC to shorten gns names, return shorten_handle */
345  struct LookupMessage *lookup_msg;
347  size_t nlen;
348 
349  if (NULL == name)
350  {
351  GNUNET_break (0);
352  return NULL;
353  }
355  "Trying to lookup `%s' in GNS\n",
356  name);
357  nlen = strlen (name) + 1;
358  if (nlen >= GNUNET_MAX_MESSAGE_SIZE - sizeof(*lr))
359  {
360  GNUNET_break (0);
361  return NULL;
362  }
363  lr = GNUNET_new (struct GNUNET_GNS_LookupRequest);
364  lr->gns_handle = handle;
365  lr->lookup_proc = proc;
366  lr->proc_cls = proc_cls;
367  lr->r_id = handle->r_id_gen++;
368  lr->env = GNUNET_MQ_msg_extra (lookup_msg,
369  nlen,
371  lookup_msg->id = htonl (lr->r_id);
372  lookup_msg->options = htons ((uint16_t) options);
373  lookup_msg->zone = *zone;
374  lookup_msg->type = htonl (type);
375  GNUNET_memcpy (&lookup_msg[1],
376  name,
377  nlen);
379  handle->lookup_tail,
380  lr);
381  if (NULL != handle->mq)
382  GNUNET_MQ_send_copy (handle->mq,
383  lr->env);
384  return lr;
385 }
386 
387 
388 /* end of gns_api.c */
uint32_t r_id
request id
Definition: gns_api.c:77
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
Connection to the GNS service.
Definition: gns_api.h:35
Message from client to GNS service to lookup records.
Definition: gns.h:36
const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration to use.
Definition: gns_api.h:40
Message from GNS service to client: new results.
Definition: gns.h:76
uint32_t id
Unique identifier for this request (for key collisions).
Definition: gns.h:46
struct GNUNET_GNS_Handle * gns_handle
handle to gns
Definition: gns_api.c:57
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
uint32_t rd_count
The number of records contained in response.
Definition: gns.h:91
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
void(* GNUNET_GNS_LookupResultProcessor)(void *cls, uint32_t rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Iterator called on obtained result for a GNS lookup.
static struct GNUNET_GNS_LookupWithTldRequest * lr
Handle to lookup request.
Definition: gnunet-gns.c:75
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
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:1057
struct GNUNET_CRYPTO_EcdsaPublicKey zone
Zone that is to be used for lookup.
Definition: gns.h:51
GNUNET_MQ_Error
Error codes for the queue.
#define GNUNET_MESSAGE_TYPE_GNS_LOOKUP
Client would like to resolve a name.
struct GNUNET_GNS_LookupRequest * next
DLL.
Definition: gns_api.c:47
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct GNUNET_TIME_Relative reconnect_backoff
How long do we wait until we try to reconnect?
Definition: gns_api.h:65
shared data structures of libgnunetgns
Handle to a lookup request.
Definition: gns_api.c:42
#define GNUNET_MESSAGE_TYPE_GNS_LOOKUP_RESULT
Service response to name resolution request from client.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
GNUNET_GNS_LocalOptions
Options for the GNS lookup.
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
int32_t type
the type of record to look up
Definition: gns.h:67
#define GNUNET_new(type)
Allocate a struct or union of the given type.
int GNUNET_GNSRECORD_records_deserialize(size_t len, const char *src, unsigned int rd_count, struct GNUNET_GNSRECORD_Data *dest)
Deserialize the given records to the given destination.
GNUNET_GNS_LookupResultProcessor lookup_proc
processor to call on lookup result
Definition: gns_api.c:62
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
IPC messages between GNS API and GNS service.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static char * zone
Name of the zone we manage.
#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:52
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:1253
uint32_t id
Unique identifier for this request (for key collisions).
Definition: gns.h:86
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
void GNUNET_GNS_disconnect(struct GNUNET_GNS_Handle *handle)
Shutdown connection with the GNS service.
Definition: gns_api.c:284
struct GNUNET_MQ_Handle * mq
Connection to service (if available).
Definition: gns_api.h:45
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
static int result
Global testing status.
static void force_reconnect(struct GNUNET_GNS_Handle *handle)
Disconnect from service and then reconnect.
Definition: gns_api.c:111
static void reconnect(struct GNUNET_GNS_Handle *handle)
Reconnect to GNS service.
Definition: gns_api.c:227
struct GNUNET_GNS_Handle * GNUNET_GNS_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Initialize the connection with the GNS service.
Definition: gns_api.c:262
struct GNUNET_GNS_LookupRequest * lookup_tail
Tail of linked list of active lookup requests.
Definition: gns_api.h:55
struct GNUNET_GNS_LookupRequest * prev
DLL.
Definition: gns_api.c:52
Message handler for a specific message type.
int16_t options
Local options for where to look for results (an enum GNUNET_GNS_LocalOptions in NBO).
Definition: gns.h:57
void GNUNET_MQ_discard(struct GNUNET_MQ_Envelope *mqm)
Discard the message queue message, free all allocated resources.
Definition: mq.c:321
struct GNUNET_MQ_Envelope * env
Envelope with the message for this queue entry.
Definition: gns_api.c:72
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
static int check_result(void *cls, const struct LookupResultMessage *lookup_msg)
Check validity of message received from the GNS service.
Definition: gns_api.c:152
static void reconnect_task(void *cls)
Reconnect to GNS.
Definition: gns_api.c:96
struct GNUNET_MessageHeader header
Header of type GNUNET_MESSAGE_TYPE_GNS_LOOKUP_RESULT.
Definition: gns.h:81
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
struct GNUNET_GNS_LookupRequest * lookup_head
Head of linked list of active lookup requests.
Definition: gns_api.h:50
#define LOG(kind,...)
Definition: gns_api.c:37
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message...
configuration data
Definition: configuration.c:85
const char * name
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
void GNUNET_MQ_send_copy(struct GNUNET_MQ_Handle *mq, const struct GNUNET_MQ_Envelope *ev)
Send a copy of a message with the given message queue.
Definition: mq.c:432
uint32_t r_id_gen
Request Id generator.
Definition: gns_api.h:70
void * GNUNET_GNS_lookup_cancel(struct GNUNET_GNS_LookupRequest *lr)
Cancel pending lookup request.
Definition: gns_api.c:308
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition: mq.c:824
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...
Definition: gns_api.c:133
struct GNUNET_GNS_LookupRequest * GNUNET_GNS_lookup(struct GNUNET_GNS_Handle *handle, const char *name, const struct GNUNET_CRYPTO_EcdsaPublicKey *zone, uint32_t type, enum GNUNET_GNS_LocalOptions options, GNUNET_GNS_LookupResultProcessor proc, void *proc_cls)
Perform an asynchronous lookup operation on the GNS.
Definition: gns_api.c:336
static void handle_result(void *cls, const struct LookupResultMessage *lookup_msg)
Handler for messages received from the GNS service.
Definition: gns_api.c:180
struct GNUNET_SCHEDULER_Task * reconnect_task
Reconnect task.
Definition: gns_api.h:60
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
void * proc_cls
lookup_proc closure
Definition: gns_api.c:67
#define GNUNET_free(ptr)
Wrapper around free.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:966