GNUnet  0.10.x
namestore_api_monitor.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 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_crypto_lib.h"
29 #include "gnunet_constants.h"
30 #include "gnunet_dnsparser_lib.h"
31 #include "gnunet_arm_service.h"
32 #include "gnunet_signatures.h"
34 #include "namestore.h"
35 
36 
45 
50 
55 
59  void *error_cb_cls;
60 
65 
69  void *monitor_cls;
70 
75 
79  void *sync_cb_cls;
80 
85 
90 };
91 
92 
98 static void
100 
101 
108 static void
109 handle_sync(void *cls, const struct GNUNET_MessageHeader *msg)
110 {
111  struct GNUNET_NAMESTORE_ZoneMonitor *zm = cls;
112 
113  (void)cls;
114  (void)msg;
115  if (NULL != zm->sync_cb)
116  zm->sync_cb(zm->sync_cb_cls);
117 }
118 
119 
127 static int
128 check_result(void *cls, const struct RecordResultMessage *lrm)
129 {
130  struct GNUNET_NAMESTORE_ZoneMonitor *zm = cls;
131  size_t lrm_len;
132  size_t exp_lrm_len;
133  size_t name_len;
134  size_t rd_len;
135  unsigned rd_count;
136  const char *name_tmp;
137  const char *rd_ser_tmp;
138 
139  (void)cls;
140  if ((0 != GNUNET_memcmp(&lrm->private_key, &zm->zone)) &&
141  (0 != GNUNET_is_zero(&zm->zone)))
142  {
143  GNUNET_break(0);
144  return GNUNET_SYSERR;
145  }
146  lrm_len = ntohs(lrm->gns_header.header.size);
147  rd_len = ntohs(lrm->rd_len);
148  rd_count = ntohs(lrm->rd_count);
149  name_len = ntohs(lrm->name_len);
150  if (name_len > MAX_NAME_LEN)
151  {
152  GNUNET_break(0);
153  return GNUNET_SYSERR;
154  }
155  exp_lrm_len = sizeof(struct RecordResultMessage) + name_len + rd_len;
156  if (lrm_len != exp_lrm_len)
157  {
158  GNUNET_break(0);
159  return GNUNET_SYSERR;
160  }
161  if (0 == name_len)
162  {
163  GNUNET_break(0);
164  return GNUNET_SYSERR;
165  }
166  name_tmp = (const char *)&lrm[1];
167  if (name_tmp[name_len - 1] != '\0')
168  {
169  GNUNET_break(0);
170  return GNUNET_SYSERR;
171  }
172  rd_ser_tmp = (const char *)&name_tmp[name_len];
173  {
174  struct GNUNET_GNSRECORD_Data rd[rd_count];
175 
176  if (GNUNET_OK !=
177  GNUNET_GNSRECORD_records_deserialize(rd_len, rd_ser_tmp, rd_count, rd))
178  {
179  GNUNET_break(0);
180  return GNUNET_SYSERR;
181  }
182  }
183  return GNUNET_OK;
184 }
185 
186 
194 static void
195 handle_result(void *cls, const struct RecordResultMessage *lrm)
196 {
197  struct GNUNET_NAMESTORE_ZoneMonitor *zm = cls;
198  size_t name_len;
199  size_t rd_len;
200  unsigned rd_count;
201  const char *name_tmp;
202  const char *rd_ser_tmp;
203 
204  rd_len = ntohs(lrm->rd_len);
205  rd_count = ntohs(lrm->rd_count);
206  name_len = ntohs(lrm->name_len);
207  name_tmp = (const char *)&lrm[1];
208  rd_ser_tmp = (const char *)&name_tmp[name_len];
209  {
210  struct GNUNET_GNSRECORD_Data rd[rd_count];
211 
213  GNUNET_OK ==
214  GNUNET_GNSRECORD_records_deserialize(rd_len, rd_ser_tmp, rd_count, rd));
215  zm->monitor(zm->monitor_cls, &lrm->private_key, name_tmp, rd_count, rd);
216  }
217 }
218 
219 
228 static void
229 mq_error_handler(void *cls, enum GNUNET_MQ_Error error)
230 {
231  struct GNUNET_NAMESTORE_ZoneMonitor *zm = cls;
232 
233  (void)error;
234  reconnect(zm);
235 }
236 
237 
243 static void
245 {
246  struct GNUNET_MQ_MessageHandler handlers[] =
249  struct GNUNET_MessageHeader,
250  zm),
253  struct RecordResultMessage,
254  zm),
256  struct GNUNET_MQ_Envelope *env;
257  struct ZoneMonitorStartMessage *sm;
258 
259  if (NULL != zm->mq)
260  {
261  GNUNET_MQ_destroy(zm->mq);
262  zm->error_cb(zm->error_cb_cls);
263  }
264  zm->mq = GNUNET_CLIENT_connect(zm->cfg,
265  "namestore",
266  handlers,
268  zm);
269  if (NULL == zm->mq)
270  return;
272  sm->iterate_first = htonl(zm->iterate_first);
273  sm->zone = zm->zone;
274  GNUNET_MQ_send(zm->mq, env);
275 }
276 
277 
303  const struct GNUNET_CONFIGURATION_Handle *cfg,
304  const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
305  int iterate_first,
307  void *error_cb_cls,
309  void *monitor_cls,
311  void *sync_cb_cls)
312 {
314 
316  if (NULL != zone)
317  zm->zone = *zone;
319  zm->error_cb = error_cb;
321  zm->monitor = monitor;
322  zm->monitor_cls = monitor_cls;
323  zm->sync_cb = sync_cb;
324  zm->sync_cb_cls = sync_cb_cls;
325  zm->cfg = cfg;
326  reconnect(zm);
327  if (NULL == zm->mq)
328  {
329  GNUNET_free(zm);
330  return NULL;
331  }
332  return zm;
333 }
334 
335 
357 void
359  uint64_t limit)
360 {
361  struct GNUNET_MQ_Envelope *env;
362  struct ZoneMonitorNextMessage *nm;
363 
365  nm->limit = GNUNET_htonll(limit);
366  GNUNET_MQ_send(zm->mq, env);
367 }
368 
369 
375 void
377 {
378  if (NULL != zm->mq)
379  {
380  GNUNET_MQ_destroy(zm->mq);
381  zm->mq = NULL;
382  }
383  GNUNET_free(zm);
384 }
385 
386 /* end of namestore_api_monitor.c */
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
Start monitoring a zone.
Definition: namestore.h:291
struct GNUNET_MQ_Handle * mq
Handle to namestore service.
void * error_cb_cls
Closure for error_cb.
struct GNUNET_NAMESTORE_ZoneMonitor * GNUNET_NAMESTORE_zone_monitor_start(const struct GNUNET_CONFIGURATION_Handle *cfg, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, int iterate_first, GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls, GNUNET_NAMESTORE_RecordMonitor monitor, void *monitor_cls, GNUNET_SCHEDULER_TaskCallback sync_cb, void *sync_cb_cls)
Begin monitoring a zone for changes.
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:900
#define GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_NEXT
Client to service: I am now ready for the next (set of) monitor events.
GNUNET_MQ_Error
Error codes for the queue.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
void(* GNUNET_NAMESTORE_RecordMonitor)(void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Process a record that was stored in the namestore.
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
void GNUNET_NAMESTORE_zone_monitor_stop(struct GNUNET_NAMESTORE_ZoneMonitor *zm)
Stop monitoring a zone for changes.
static struct GNUNET_NAMESTORE_ZoneMonitor * zm
Monitor handle.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
static void reconnect(struct GNUNET_NAMESTORE_ZoneMonitor *zm)
Reconnect to the namestore service.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
Private ECC key encoded for transmission.
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.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration (to reconnect).
void(* GNUNET_SCHEDULER_TaskCallback)(void *cls)
Signature of the main function of a task.
GNUNET_SCHEDULER_TaskCallback sync_cb
Function called when we&#39;ve synchronized.
uint16_t name_len
Name length.
Definition: namestore.h:259
GNUNET_NAMESTORE_RecordMonitor monitor
Function to call on events.
common internal definitions for namestore service
struct GNUNET_MessageHeader header
header.type will be GNUNET_MESSAGE_TYPE_NAMESTORE_* header.size will be message size ...
Definition: namestore.h:45
struct GNUNET_CRYPTO_EcdsaPrivateKey private_key
The private key of the authority.
Definition: namestore.h:279
uint64_t limit
Number of records to return to the iterator in one shot (before #GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_M...
Definition: namestore.h:329
cryptographic primitives for GNUnet
Handle for a monitoring activity.
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...
uint16_t rd_count
Number of records contained.
Definition: namestore.h:269
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
int iterate_first
Do we first iterate over all existing records?
struct GNUNET_CRYPTO_EcdsaPrivateKey zone
Zone key.
Definition: namestore.h:306
static int result
Global testing status.
static void handle_result(void *cls, const struct RecordResultMessage *lrm)
We&#39;ve received a notification about a change to our zone.
Message handler for a specific message type.
uint64_t GNUNET_htonll(uint64_t n)
Convert unsigned 64-bit integer to network byte order.
Definition: common_endian.c:35
void * sync_cb_cls
Closure for sync_cb.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
static void handle_sync(void *cls, const struct GNUNET_MessageHeader *msg)
Handle SYNC message from the namestore service.
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
uint16_t rd_len
Length of serialized record data.
Definition: namestore.h:264
#define GNUNET_is_zero(a)
Check that memory in a is all zeros.
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT.
Definition: namestore.h:254
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
uint32_t iterate_first
GNUNET_YES to first iterate over all records, GNUNET_NO to only monitor changes.o ...
Definition: namestore.h:301
Ask for next result of zone iteration for the given operation.
Definition: namestore.h:313
static int check_result(void *cls, const struct RecordResultMessage *lrm)
We&#39;ve received a notification about a change to our zone.
Handle to a message queue.
Definition: mq.c:84
configuration data
Definition: configuration.c:83
#define MAX_NAME_LEN
Maximum length of any name, including 0-termination.
Definition: namecache.h:33
#define GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_SYNC
Service to client: you&#39;re now in sync.
#define GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_START
Client to service: start monitoring (yields sequence of "ZONE_ITERATION_RESPONSES" — forever)...
GNUNET_SCHEDULER_TaskCallback error_cb
Function to call on errors.
Header for all communications.
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition: mq.c:821
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:351
#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT
Service to client: here is a (plaintext) record you requested.
Record is returned from the namestore (as authority).
Definition: namestore.h:250
struct GNUNET_CRYPTO_EcdsaPrivateKey zone
Monitored zone.
void GNUNET_NAMESTORE_zone_monitor_next(struct GNUNET_NAMESTORE_ZoneMonitor *zm, uint64_t limit)
Calls the monitor processor specified in GNUNET_NAMESTORE_zone_monitor_start for the next record(s)...
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
void * monitor_cls
Closure for monitor.
#define GNUNET_free(ptr)
Wrapper around free.