GNUnet  0.11.x
gnunet-service-testbed_barriers.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2008--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 
27 #include "gnunet-service-testbed.h"
29 #include "testbed_api.h"
30 
31 
35 #define MESSAGE_SEND_TIMEOUT(s) \
36  GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, s)
37 
38 
42 #define LOCAL_QUORUM_REACHED(barrier) \
43  ((barrier->quorum * GST_num_local_peers) <= (barrier->nreached * 100))
44 
45 
46 #ifdef LOG
47 #undef LOG
48 #endif
49 
53 #define LOG(kind, ...) \
54  GNUNET_log_from (kind, "testbed-barriers", __VA_ARGS__)
55 
56 
60 struct Barrier;
61 
62 
66 struct ClientCtx
67 {
71  struct Barrier *barrier;
72 
76  struct ClientCtx *next;
77 
81  struct ClientCtx *prev;
82 
87 };
88 
89 
93 struct WBarrier
94 {
98  struct WBarrier *next;
99 
103  struct WBarrier *prev;
104 
108  struct Barrier *barrier;
109 
114 
119 
123  uint8_t reached;
124 };
125 
126 
130 struct Barrier
131 {
135  struct GNUNET_HashCode hash;
136 
141 
145  char *name;
146 
150  struct ClientCtx *head;
151 
155  struct ClientCtx *tail;
156 
160  struct WBarrier *whead;
161 
165  struct WBarrier *wtail;
166 
171 
176 
180  unsigned int num_wbarriers;
181 
185  unsigned int num_wbarriers_reached;
186 
190  unsigned int num_wbarriers_inited;
191 
195  unsigned int nreached;
196 
200  unsigned int nslaves;
201 
205  uint8_t quorum;
206 };
207 
208 
213 
217 static struct GNUNET_SERVICE_Handle *ctx;
218 
219 
226 static void
228 {
229  struct ClientCtx *ctx;
230 
233  &barrier->hash,
234  barrier));
235  while (NULL != (ctx = barrier->head))
236  {
238  barrier->tail,
239  ctx);
240  ctx->barrier = NULL;
241  }
242  GNUNET_free (barrier->name);
243  GNUNET_free (barrier);
244 }
245 
246 
252 static void
254 {
255  struct WBarrier *wrapper;
256 
257  while (NULL != (wrapper = barrier->whead))
258  {
261  barrier->wtail,
262  wrapper);
263  GNUNET_free (wrapper);
264  }
265 }
266 
267 
277 static void
279  const char *name,
281  const char *emsg)
282 {
283  struct GNUNET_MQ_Envelope *env;
285  size_t name_len;
286  size_t err_len;
287 
288  GNUNET_assert ((NULL == emsg) ||
290  name_len = strlen (name) + 1;
291  err_len = ((NULL == emsg) ? 0 : (strlen (emsg) + 1));
292  env = GNUNET_MQ_msg_extra (msg,
293  name_len + err_len,
295  msg->status = htons (status);
296  msg->name_len = htons ((uint16_t) name_len - 1);
297  GNUNET_memcpy (msg->data,
298  name,
299  name_len);
300  GNUNET_memcpy (msg->data + name_len,
301  emsg,
302  err_len);
304  env);
305 }
306 
307 
315 static void
317  const char *emsg)
318 {
319  GNUNET_assert (0 != barrier->status);
320  send_client_status_msg (barrier->mc,
321  barrier->name,
322  barrier->status,
323  emsg);
324 }
325 
326 
333 static int
335  const struct GNUNET_TESTBED_BarrierWait *msg)
336 {
337  return GNUNET_OK; /* always well-formed */
338 }
339 
340 
352 static void
354  const struct GNUNET_TESTBED_BarrierWait *msg)
355 {
356  struct ClientCtx *client_ctx = cls;
357  struct Barrier *barrier;
358  char *name;
359  struct GNUNET_HashCode key;
360  size_t name_len;
361  uint16_t msize;
362 
363  msize = ntohs (msg->header.size);
364  if (NULL == barrier_map)
365  {
366  GNUNET_break (0);
367  GNUNET_SERVICE_client_drop (client_ctx->client);
368  return;
369  }
370  name_len = msize - sizeof(struct GNUNET_TESTBED_BarrierWait);
371  name = GNUNET_malloc (name_len + 1);
372  name[name_len] = '\0';
373  GNUNET_memcpy (name,
374  msg->name,
375  name_len);
376  LOG_DEBUG ("Received BARRIER_WAIT for barrier `%s'\n",
377  name);
378  GNUNET_CRYPTO_hash (name,
379  name_len,
380  &key);
381  GNUNET_free (name);
382  if (NULL == (barrier = GNUNET_CONTAINER_multihashmap_get (barrier_map, &key)))
383  {
384  GNUNET_break (0);
385  GNUNET_SERVICE_client_drop (client_ctx->client);
386  return;
387  }
388  if (NULL != client_ctx->barrier)
389  {
390  GNUNET_break (0);
391  GNUNET_SERVICE_client_drop (client_ctx->client);
392  return;
393  }
394  client_ctx->barrier = barrier;
396  barrier->tail,
397  client_ctx);
398  barrier->nreached++;
399  if ((barrier->num_wbarriers_reached == barrier->num_wbarriers) &&
400  (LOCAL_QUORUM_REACHED (barrier)))
401  {
403  send_barrier_status_msg (barrier,
404  NULL);
405  }
407 }
408 
409 
418 static void *
419 connect_cb (void *cls,
421  struct GNUNET_MQ_Handle *mq)
422 {
423  struct ClientCtx *client_ctx;
424 
425  LOG_DEBUG ("Client connected to testbed-barrier service\n");
426  client_ctx = GNUNET_new (struct ClientCtx);
427  client_ctx->client = client;
428  return client_ctx;
429 }
430 
431 
440 static void
441 disconnect_cb (void *cls,
443  void *app_ctx)
444 {
445  struct ClientCtx *client_ctx = app_ctx;
446  struct Barrier *barrier = client_ctx->barrier;
447 
448  if (NULL != barrier)
449  {
451  barrier->tail,
452  client_ctx);
453  client_ctx->barrier = NULL;
454  }
455  GNUNET_free (client_ctx);
456  LOG_DEBUG ("Client disconnected from testbed-barrier service\n");
457 }
458 
459 
465 void
467 {
468  struct GNUNET_MQ_MessageHandler message_handlers[] = {
469  GNUNET_MQ_hd_var_size (barrier_wait,
472  NULL),
474  };
475 
476  LOG_DEBUG ("Launching testbed-barrier service\n");
477  barrier_map = GNUNET_CONTAINER_multihashmap_create (3,
478  GNUNET_YES);
479  ctx = GNUNET_SERVICE_start ("testbed-barrier",
480  cfg,
481  &connect_cb,
482  &disconnect_cb,
483  NULL,
484  message_handlers);
485 }
486 
487 
498 static int
500  const struct GNUNET_HashCode *key,
501  void *value)
502 {
503  struct Barrier *barrier = value;
504 
505  GNUNET_assert (NULL != barrier);
506  cancel_wrappers (barrier);
507  remove_barrier (barrier);
508  return GNUNET_YES;
509 }
510 
511 
515 void
517 {
518  GNUNET_assert (NULL != barrier_map);
521  &
523  NULL));
525  GNUNET_assert (NULL != ctx);
526  GNUNET_SERVICE_stop (ctx);
527 }
528 
529 
543 static void
545  const char *name,
546  struct GNUNET_TESTBED_Barrier *b_,
548  const char *emsg)
549 {
550  struct WBarrier *wrapper = cls;
551  struct Barrier *barrier = wrapper->barrier;
552 
553  GNUNET_assert (b_ == wrapper->hbarrier);
554  switch (status)
555  {
558  "Initialising barrier `%s' failed at a sub-controller: %s\n",
559  barrier->name,
560  (NULL != emsg) ? emsg : "NULL");
561  cancel_wrappers (barrier);
562  if (NULL == emsg)
563  emsg = "Initialisation failed at a sub-controller";
565  send_barrier_status_msg (barrier, emsg);
566  return;
567 
570  {
571  GNUNET_break_op (0);
572  return;
573  }
574  barrier->num_wbarriers_reached++;
575  if ((barrier->num_wbarriers_reached == barrier->num_wbarriers)
576  && (LOCAL_QUORUM_REACHED (barrier)))
577  {
579  send_barrier_status_msg (barrier, NULL);
580  }
581  return;
582 
584  if (0 != barrier->status)
585  {
586  GNUNET_break_op (0);
587  return;
588  }
589  barrier->num_wbarriers_inited++;
590  if (barrier->num_wbarriers_inited == barrier->num_wbarriers)
591  {
593  send_barrier_status_msg (barrier, NULL);
594  }
595  return;
596  }
597 }
598 
599 
606 static void
608 {
609  struct Barrier *barrier = cls;
610 
611  cancel_wrappers (barrier);
613  send_barrier_status_msg (barrier,
614  "Timedout while propagating barrier initialisation\n");
615  remove_barrier (barrier);
616 }
617 
618 
626 int
628  const struct GNUNET_TESTBED_BarrierInit *msg)
629 {
630  return GNUNET_OK; /* always well-formed */
631 }
632 
633 
645 void
647  const struct GNUNET_TESTBED_BarrierInit *msg)
648 {
649  struct GNUNET_SERVICE_Client *client = cls;
650  char *name;
651  struct Barrier *barrier;
652  struct Slave *slave;
653  struct WBarrier *wrapper;
654  struct GNUNET_HashCode hash;
655  size_t name_len;
656  unsigned int cnt;
657  uint16_t msize;
658 
659  if (NULL == GST_context)
660  {
661  GNUNET_break_op (0);
663  return;
664  }
665  if (client != GST_context->client)
666  {
667  GNUNET_break_op (0);
669  return;
670  }
671  msize = ntohs (msg->header.size);
672  name_len = (size_t) msize - sizeof(struct GNUNET_TESTBED_BarrierInit);
673  name = GNUNET_malloc (name_len + 1);
674  GNUNET_memcpy (name, msg->name, name_len);
675  GNUNET_CRYPTO_hash (name, name_len, &hash);
676  LOG_DEBUG ("Received BARRIER_INIT for barrier `%s'\n",
677  name);
678  if (GNUNET_YES ==
680  &hash))
681  {
682  send_client_status_msg (client,
683  name,
685  "A barrier with the same name already exists");
686  GNUNET_free (name);
688  return;
689  }
690  barrier = GNUNET_new (struct Barrier);
691  barrier->hash = hash;
692  barrier->quorum = msg->quorum;
693  barrier->name = name;
694  barrier->mc = client;
697  &barrier->hash,
698  barrier,
701  /* Propagate barrier init to subcontrollers */
702  for (cnt = 0; cnt < GST_slave_list_size; cnt++)
703  {
704  if (NULL == (slave = GST_slave_list[cnt]))
705  continue;
706  if (NULL == slave->controller)
707  {
708  GNUNET_break (0); /* May happen when we are connecting to the controller */
709  continue;
710  }
711  wrapper = GNUNET_new (struct WBarrier);
712  wrapper->barrier = barrier;
713  wrapper->controller = slave->controller;
715  barrier->wtail,
716  wrapper);
717  barrier->num_wbarriers++;
718  wrapper->hbarrier = GNUNET_TESTBED_barrier_init_ (wrapper->controller,
719  barrier->name,
720  barrier->quorum,
722  wrapper,
723  GNUNET_NO);
724  }
725  if (NULL == barrier->whead) /* No further propagation */
726  {
728  LOG_DEBUG (
729  "Sending GNUNET_TESTBED_BARRIERSTATUS_INITIALISED for barrier `%s'\n",
730  barrier->name);
731  send_barrier_status_msg (barrier, NULL);
732  }
733  else
735  30),
737  barrier);
738 }
739 
740 
748 int
750  const struct GNUNET_TESTBED_BarrierCancel *msg)
751 {
752  return GNUNET_OK; /* all are well-formed */
753 }
754 
755 
767 void
769  const struct GNUNET_TESTBED_BarrierCancel *msg)
770 {
771  struct GNUNET_SERVICE_Client *client = cls;
772  char *name;
773  struct Barrier *barrier;
774  struct GNUNET_HashCode hash;
775  size_t name_len;
776  uint16_t msize;
777 
778  if (NULL == GST_context)
779  {
780  GNUNET_break_op (0);
782  return;
783  }
784  if (client != GST_context->client)
785  {
786  GNUNET_break_op (0);
788  return;
789  }
790  msize = ntohs (msg->header.size);
791  name_len = msize - sizeof(struct GNUNET_TESTBED_BarrierCancel);
792  name = GNUNET_malloc (name_len + 1);
793  GNUNET_memcpy (name,
794  msg->name,
795  name_len);
796  LOG_DEBUG ("Received BARRIER_CANCEL for barrier `%s'\n",
797  name);
798  GNUNET_CRYPTO_hash (name,
799  name_len,
800  &hash);
801  if (GNUNET_NO ==
803  &hash))
804  {
805  GNUNET_break_op (0);
807  return;
808  }
809  barrier = GNUNET_CONTAINER_multihashmap_get (barrier_map,
810  &hash);
811  GNUNET_assert (NULL != barrier);
812  cancel_wrappers (barrier);
813  remove_barrier (barrier);
815 }
816 
817 
825 int
827  const struct GNUNET_TESTBED_BarrierStatusMsg *msg)
828 {
829  uint16_t msize;
830  uint16_t name_len;
831  const char *name;
833 
834  msize = ntohs (msg->header.size) - sizeof(*msg);
835  status = ntohs (msg->status);
837  {
838  GNUNET_break_op (0); /* current we only expect BARRIER_CROSSED
839  status message this way */
840  return GNUNET_SYSERR;
841  }
842  name = msg->data;
843  name_len = ntohs (msg->name_len);
844  if ((name_len + 1) != msize)
845  {
846  GNUNET_break_op (0);
847  return GNUNET_SYSERR;
848  }
849  if ('\0' != name[name_len])
850  {
851  GNUNET_break_op (0);
852  return GNUNET_SYSERR;
853  }
854  return GNUNET_OK;
855 }
856 
857 
866 void
868  const struct GNUNET_TESTBED_BarrierStatusMsg *msg)
869 {
870  struct GNUNET_SERVICE_Client *client = cls;
871  struct Barrier *barrier;
872  struct ClientCtx *client_ctx;
873  struct WBarrier *wrapper;
874  const char *name;
875  struct GNUNET_HashCode key;
876  uint16_t name_len;
877  struct GNUNET_MQ_Envelope *env;
878 
879  if (NULL == GST_context)
880  {
881  GNUNET_break_op (0);
883  return;
884  }
885  if (client != GST_context->client)
886  {
887  GNUNET_break_op (0);
889  return;
890  }
891  name = msg->data;
892  name_len = ntohs (msg->name_len);
893  LOG_DEBUG ("Received BARRIER_STATUS for barrier `%s'\n",
894  name);
895  GNUNET_CRYPTO_hash (name,
896  name_len,
897  &key);
898  barrier = GNUNET_CONTAINER_multihashmap_get (barrier_map,
899  &key);
900  if (NULL == barrier)
901  {
902  GNUNET_break_op (0);
904  return;
905  }
907  for (client_ctx = barrier->head; NULL != client_ctx; client_ctx =
908  client_ctx->next) /* Notify peers */
909  {
910  env = GNUNET_MQ_msg_copy (&msg->header);
912  env);
913  }
918  for (wrapper = barrier->whead; NULL != wrapper; wrapper = wrapper->next)
919  {
921  GNUNET_copy_message (&msg->header));
922  }
923 }
924 
925 
926 /* end of gnunet-service-testbed_barriers.c */
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS
Message for signalling status of a barrier.
Interface for the barrier initialisation handler routine.
struct WBarrier * wtail
DLL tail for the list of barrier handles.
struct GNUNET_MQ_Envelope * GNUNET_MQ_msg_copy(const struct GNUNET_MessageHeader *hdr)
Create a new envelope by copying an existing message.
Definition: mq.c:653
unsigned int num_wbarriers_reached
Number of wrapped barriers reached so far.
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
void GST_barriers_destroy()
Function to stop the barrier service.
struct WBarrier * next
DLL next pointer.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
Context to be associated with each client.
Handle to interact with a GNUnet testbed controller.
Definition: testbed_api.h:193
char name[0]
The name of the barrier they have reached.
Definition: testbed.h:860
Message to cancel a barrier.
Definition: testbed.h:804
Handle to a service.
Definition: service.c:116
static struct GNUNET_CONTAINER_MultiHashMap * barrier_map
Hashtable handle for storing initialised barriers.
data structures shared amongst components of TESTBED service
uint16_t name_len
strlen of the barrier name
Definition: testbed.h:836
struct GNUNET_MQ_Handle * GNUNET_SERVICE_client_get_mq(struct GNUNET_SERVICE_Client *c)
Obtain the message queue of c.
Definition: service.c:2437
int check_barrier_init(void *cls, const struct GNUNET_TESTBED_BarrierInit *msg)
Check GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_INIT messages.
static int check_barrier_wait(void *cls, const struct GNUNET_TESTBED_BarrierWait *msg)
Check GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_WAIT messages.
#define GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_WAIT
Message sent by a peer when it has reached a barrier and is waiting for it to be crossed.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
struct GNUNET_SERVICE_Handle * GNUNET_SERVICE_start(const char *service_name, const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_SERVICE_ConnectHandler connect_cb, GNUNET_SERVICE_DisconnectHandler disconnect_cb, void *cls, const struct GNUNET_MQ_MessageHandler *handlers)
Low-level function to start a service if the scheduler is already running.
Definition: service.c:1878
void handle_barrier_status(void *cls, const struct GNUNET_TESTBED_BarrierStatusMsg *msg)
Message handler for GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS messages.
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_new(type)
Allocate a struct or union of the given type.
Structure representing a connected(directly-linked) controller.
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS.
Definition: testbed.h:826
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
int GNUNET_CONTAINER_multihashmap_contains(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Check if the map contains any value under the given key (including values that are NULL)...
static void send_barrier_status_msg(struct Barrier *barrier, const char *emsg)
Sends a barrier failed message.
struct GNUNET_TESTBED_Barrier * hbarrier
The barrier handle from API.
enum GNUNET_TESTBED_BarrierStatus status
The status of this barrier.
Internal representation of the hash map.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_CANCEL.
Definition: testbed.h:809
Message sent from peers to the testbed-barrier service to indicate that they have reached a barrier a...
Definition: testbed.h:850
GNUNET_TESTBED_BarrierStatus
Status of a barrier.
unsigned int num_wbarriers
Number of barriers wrapped in the above DLL.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
uint16_t status
status.
Definition: testbed.h:831
Handle to a client that is connected to a service.
Definition: service.c:250
struct ClientCtx * next
DLL next ptr.
#define MESSAGE_SEND_TIMEOUT(s)
timeout for outgoing message transmissions in seconds
#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
int check_barrier_cancel(void *cls, const struct GNUNET_TESTBED_BarrierCancel *msg)
Check GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_CANCEL messages.
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
void * cls
Closure for mv and cb.
, &#39; bother checking if a value already exists (faster than GNUNET_CONTAINER_MULTIHASHMAPOPTION_...
static char * value
Value of the record to add/remove.
void handle_barrier_init(void *cls, const struct GNUNET_TESTBED_BarrierInit *msg)
Message handler for GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_INIT messages.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:48
struct ClientCtx * prev
DLL prev ptr.
struct WBarrier * whead
DLL head for the list of barrier handles.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
unsigned int nreached
Number of peers which have reached this barrier.
void GST_barriers_init(struct GNUNET_CONFIGURATION_Handle *cfg)
Function to initialise barrriers component.
static void cancel_wrappers(struct Barrier *barrier)
Cancels all subcontroller barrier handles.
static struct GNUNET_SERVICE_Handle * ctx
Service context.
struct GNUNET_SERVICE_Client * client
The client handle associated with this context.
uint16_t status
See PRISM_STATUS_*-constants.
int GNUNET_CONTAINER_multihashmap_remove(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Remove the given key-value pair from the map.
struct GNUNET_TESTBED_Controller * controller
Handle to the slave controller where this wrapper creates a barrier.
char name[0]
The barrier name.
Definition: testbed.h:814
void GNUNET_TESTBED_barrier_cancel(struct GNUNET_TESTBED_Barrier *barrier)
Cancel a barrier.
Definition: testbed_api.c:2458
void GNUNET_SERVICE_stop(struct GNUNET_SERVICE_Handle *srv)
Stops a service that was started with GNUNET_SERVICE_start().
Definition: service.c:1911
static void handle_barrier_wait(void *cls, const struct GNUNET_TESTBED_BarrierWait *msg)
Message handler for GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_WAIT messages.
Handle for barrier.
Definition: testbed_api.h:277
A 512-bit hashcode.
static void disconnect_cb(void *cls, struct GNUNET_SERVICE_Client *client, void *app_ctx)
Functions with this signature are called whenever a client is disconnected on the network level...
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2324
struct GNUNET_HashCode hash
The hashcode of the barrier name.
Message handler for a specific message type.
struct GNUNET_TESTBED_Barrier * GNUNET_TESTBED_barrier_init_(struct GNUNET_TESTBED_Controller *controller, const char *name, unsigned int quorum, GNUNET_TESTBED_barrier_status_cb cb, void *cls, int echo)
Initialise a barrier and call the given callback when the required percentage of peers (quorum) reach...
Definition: testbed_api.c:2370
struct GNUNET_SERVICE_Client * mc
The client handle to the master controller.
uint8_t reached
Has this barrier been crossed?
unsigned int nslaves
Number of slaves we have initialised this barrier.
struct GNUNET_HashCode key
The key used in the DHT.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
char data[0]
the barrier name (0-terminated) concatenated with an error message (0-terminated) if the status were ...
Definition: testbed.h:842
int check_barrier_status(void *cls, const struct GNUNET_TESTBED_BarrierStatusMsg *msg)
Check GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS messages.
void GNUNET_TESTBED_queue_message_(struct GNUNET_TESTBED_Controller *controller, struct GNUNET_MessageHeader *msg)
Queues a message in send queue for sending to the service.
Definition: testbed_api.c:1335
unsigned int num_wbarriers_inited
Number of wrapped barrier initialised so far.
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_INIT.
Definition: testbed.h:787
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
int GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
static void wbarrier_status_cb(void *cls, const char *name, struct GNUNET_TESTBED_Barrier *b_, enum GNUNET_TESTBED_BarrierStatus status, const char *emsg)
Functions of this type are to be given as callback argument to GNUNET_TESTBED_barrier_init().
#define LOG(kind,...)
Logging shorthand.
#define LOCAL_QUORUM_REACHED(barrier)
Test to see if local peers have reached the required quorum of a barrier.
static void * connect_cb(void *cls, struct GNUNET_SERVICE_Client *client, struct GNUNET_MQ_Handle *mq)
Function called when a client connects to the testbed-barrier service.
Interface for functions internally exported from testbed_api.c.
Handle to a message queue.
Definition: mq.c:85
char * name
The name of the barrier.
uint8_t quorum
Quorum percentage to be reached.
struct GNUNET_SERVICE_Client * client
The client handle.
configuration data
Definition: configuration.c:85
const char * name
struct Context * GST_context
The master context; generated with the first INIT message.
struct WBarrier * prev
DLL prev pointer.
struct ClientCtx * head
DLL head for the list of clients waiting for this barrier.
struct GNUNET_SCHEDULER_Task * tout_task
Identifier for the timeout task.
struct ClientCtx * tail
DLL tail for the list of clients waiting for this barrier.
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
Wrapper around Barrier handle.
Entry in list of pending tasks.
Definition: scheduler.c:134
uint8_t quorum
The quorum percentage needed for crossing the barrier.
Definition: testbed.h:792
static void fwd_tout_barrier_init(void *cls)
Function called upon timeout while waiting for a response from the subcontrollers to barrier init mes...
struct GNUNET_TESTBED_Controller * controller
The controller handle.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
Barrier initialised successfully.
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_WAIT.
Definition: testbed.h:855
static int barrier_destroy_iterator(void *cls, const struct GNUNET_HashCode *key, void *value)
Iterator over hash map entries.
#define GNUNET_YES
Definition: gnunet_common.h:77
Message for signalling status changes of a barrier.
Definition: testbed.h:821
struct Barrier * barrier
The barrier this client is waiting for.
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:353
char name[0]
name of the barrier.
Definition: testbed.h:797
Message to initialise a barrier.
Definition: testbed.h:782
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MulitHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
struct Barrier * barrier
The local barrier associated with the creation of this wrapper.
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2243
#define LOG_DEBUG(...)
Debug logging shorthand.
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
static void remove_barrier(struct Barrier *barrier)
Function to remove a barrier from the barrier map and cleanup resources occupied by a barrier...
void handle_barrier_cancel(void *cls, const struct GNUNET_TESTBED_BarrierCancel *msg)
Message handler for GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_CANCEL messages.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
static void send_client_status_msg(struct GNUNET_SERVICE_Client *client, const char *name, enum GNUNET_TESTBED_BarrierStatus status, const char *emsg)
Send a status message about a barrier to the given client.
struct GNUNET_MessageHeader * GNUNET_copy_message(const struct GNUNET_MessageHeader *msg)
Create a copy of the given message.