aboutsummaryrefslogtreecommitdiff
path: root/src/testbed/gnunet-service-testbed_barriers.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/testbed/gnunet-service-testbed_barriers.c')
-rw-r--r--src/testbed/gnunet-service-testbed_barriers.c143
1 files changed, 97 insertions, 46 deletions
diff --git a/src/testbed/gnunet-service-testbed_barriers.c b/src/testbed/gnunet-service-testbed_barriers.c
index 663c090b6..68011065d 100644
--- a/src/testbed/gnunet-service-testbed_barriers.c
+++ b/src/testbed/gnunet-service-testbed_barriers.c
@@ -26,6 +26,7 @@
26 26
27#include "gnunet-service-testbed.h" 27#include "gnunet-service-testbed.h"
28#include "gnunet-service-testbed_barriers.h" 28#include "gnunet-service-testbed_barriers.h"
29#include "testbed_api_barriers.h"
29 30
30 31
31/** 32/**
@@ -328,7 +329,8 @@ cleanup_clientctx (struct ClientCtx *ctx)
328{ 329{
329 struct MessageQueue *mq; 330 struct MessageQueue *mq;
330 331
331 GNUNET_SERVER_client_drop (ctx->client); 332 if (NULL != ctx->client)
333 GNUNET_SERVER_client_drop (ctx->client);
332 if (NULL != ctx->tx) 334 if (NULL != ctx->tx)
333 GNUNET_SERVER_notify_transmit_ready_cancel (ctx->tx); 335 GNUNET_SERVER_notify_transmit_ready_cancel (ctx->tx);
334 if (NULL != (mq = ctx->mq_head)) 336 if (NULL != (mq = ctx->mq_head))
@@ -358,7 +360,13 @@ remove_barrier (struct Barrier *barrier)
358 while (NULL != (ctx = barrier->head)) 360 while (NULL != (ctx = barrier->head))
359 { 361 {
360 GNUNET_CONTAINER_DLL_remove (barrier->head, barrier->tail, ctx); 362 GNUNET_CONTAINER_DLL_remove (barrier->head, barrier->tail, ctx);
361 cleanup_clientctx (ctx); 363 GNUNET_SERVER_client_drop (ctx->client);
364 ctx->client = NULL;
365 if (NULL != ctx->tx)
366 {
367 GNUNET_SERVER_notify_transmit_ready_cancel (ctx->tx);
368 ctx->tx = NULL;
369 }
362 } 370 }
363 GNUNET_free (barrier->name); 371 GNUNET_free (barrier->name);
364 GNUNET_SERVER_client_drop (barrier->mc); 372 GNUNET_SERVER_client_drop (barrier->mc);
@@ -436,41 +444,6 @@ send_barrier_status_msg (struct Barrier *barrier, const char *emsg)
436} 444}
437 445
438 446
439
440/**
441 * Task for sending barrier crossed notifications to waiting client
442 *
443 * @param cls the barrier which is crossed
444 * @param tc scheduler task context
445 */
446static void
447notify_task_cb (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
448{
449 struct Barrier *barrier = cls;
450 struct ClientCtx *client_ctx;
451 struct GNUNET_TESTBED_BarrierStatusMsg *msg;
452 struct GNUNET_MessageHeader *dup_msg;
453 uint16_t name_len;
454 uint16_t msize;
455
456 name_len = strlen (barrier->name) + 1;
457 msize = sizeof (struct GNUNET_TESTBED_BarrierStatusMsg) + name_len;
458 msg = GNUNET_malloc (msize);
459 msg->header.size = htons (msize);
460 msg->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS);
461 msg->status = htons (BARRIER_STATUS_CROSSED);
462 msg->name_len = htons (name_len);
463 (void) memcpy (msg->data, barrier->name, name_len);
464 msg->data[name_len] = '\0';
465 while (NULL != (client_ctx = barrier->head))
466 {
467 dup_msg = GNUNET_copy_message (&msg->header);
468 queue_message (client_ctx, dup_msg);
469 GNUNET_CONTAINER_DLL_remove (barrier->head, barrier->tail, client_ctx);
470 }
471}
472
473
474/** 447/**
475 * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_WAIT messages. This 448 * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_WAIT messages. This
476 * message should come from peers or a shared helper service using the 449 * message should come from peers or a shared helper service using the
@@ -538,7 +511,6 @@ handle_barrier_wait (void *cls, struct GNUNET_SERVER_Client *client,
538 { 511 {
539 barrier->status = BARRIER_STATUS_CROSSED; 512 barrier->status = BARRIER_STATUS_CROSSED;
540 send_barrier_status_msg (barrier, NULL); 513 send_barrier_status_msg (barrier, NULL);
541 notify_task_cb (barrier, NULL);
542 } 514 }
543 GNUNET_SERVER_receive_done (client, GNUNET_OK); 515 GNUNET_SERVER_receive_done (client, GNUNET_OK);
544} 516}
@@ -560,9 +532,6 @@ disconnect_cb (void *cls, struct GNUNET_SERVER_Client *client)
560 if (NULL == client) 532 if (NULL == client)
561 return; 533 return;
562 client_ctx = GNUNET_SERVER_client_get_user_context (client, struct ClientCtx); 534 client_ctx = GNUNET_SERVER_client_get_user_context (client, struct ClientCtx);
563 if (NULL == client_ctx)
564 return; /* We only set user context for locally
565 connected clients */
566 cleanup_clientctx (client_ctx); 535 cleanup_clientctx (client_ctx);
567} 536}
568 537
@@ -777,11 +746,12 @@ GST_handle_barrier_init (void *cls, struct GNUNET_SERVER_Client *client,
777 wrapper = GNUNET_malloc (sizeof (struct WBarrier)); 746 wrapper = GNUNET_malloc (sizeof (struct WBarrier));
778 wrapper->barrier = barrier; 747 wrapper->barrier = barrier;
779 GNUNET_CONTAINER_DLL_insert_tail (barrier->whead, barrier->wtail, wrapper); 748 GNUNET_CONTAINER_DLL_insert_tail (barrier->whead, barrier->wtail, wrapper);
780 wrapper->hbarrier = GNUNET_TESTBED_barrier_init (slave->controller, 749 wrapper->hbarrier = GNUNET_TESTBED_barrier_init_ (slave->controller,
781 barrier->name, 750 barrier->name,
782 barrier->quorum, 751 barrier->quorum,
783 &wbarrier_status_cb, 752 &wbarrier_status_cb,
784 wrapper); 753 wrapper,
754 GNUNET_NO);
785 } 755 }
786 if (NULL == barrier->whead) /* No further propagation */ 756 if (NULL == barrier->whead) /* No further propagation */
787 { 757 {
@@ -856,4 +826,85 @@ GST_handle_barrier_cancel (void *cls, struct GNUNET_SERVER_Client *client,
856 GNUNET_SERVER_receive_done (client, GNUNET_OK); 826 GNUNET_SERVER_receive_done (client, GNUNET_OK);
857} 827}
858 828
829
830/**
831 * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS messages.
832 * This handler is queued in the main service and will handle the messages sent
833 * either from the testbed driver or from a high level controller
834 *
835 * @param cls NULL
836 * @param client identification of the client
837 * @param message the actual message
838 */
839void
840GST_handle_barrier_status (void *cls, struct GNUNET_SERVER_Client *client,
841 const struct GNUNET_MessageHeader *message)
842{
843 const struct GNUNET_TESTBED_BarrierStatusMsg *msg;
844 struct Barrier *barrier;
845 struct ClientCtx *client_ctx;
846 const char *name;
847 struct GNUNET_HashCode key;
848 enum GNUNET_TESTBED_BarrierStatus status;
849 uint16_t msize;
850 uint16_t name_len;
851
852 if (NULL == GST_context)
853 {
854 GNUNET_break_op (0);
855 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
856 return;
857 }
858 if (client != GST_context->client)
859 {
860 GNUNET_break_op (0);
861 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
862 return;
863 }
864 msize = ntohs (message->size);
865 if (msize <= sizeof (struct GNUNET_TESTBED_BarrierStatusMsg))
866 {
867 GNUNET_break_op (0);
868 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
869 return;
870 }
871 msg = (const struct GNUNET_TESTBED_BarrierStatusMsg *) message;
872 status = ntohs (msg->status);
873 if (BARRIER_STATUS_CROSSED != status)
874 {
875 GNUNET_break_op (0); /* current we only expect BARRIER_CROSSED
876 status message this way */
877 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
878 return;
879 }
880 name = msg->data;
881 name_len = ntohs (msg->name_len);
882 if ((sizeof (struct GNUNET_TESTBED_BarrierStatusMsg) + name_len + 1) != msize)
883 {
884 GNUNET_break_op (0);
885 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
886 return;
887 }
888 if ('\0' != name[name_len])
889 {
890 GNUNET_break_op (0);
891 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
892 return;
893 }
894 GNUNET_CRYPTO_hash (name, name_len, &key);
895 barrier = GNUNET_CONTAINER_multihashmap_get (barrier_map, &key);
896 if (NULL == barrier)
897 {
898 GNUNET_break_op (0);
899 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
900 return;
901 }
902 GNUNET_SERVER_receive_done (client, GNUNET_OK);
903 while (NULL != (client_ctx = barrier->head)) /* Notify peers */
904 {
905 queue_message (client_ctx, GNUNET_copy_message (message));
906 GNUNET_CONTAINER_DLL_remove (barrier->head, barrier->tail, client_ctx);
907 }
908}
909
859/* end of gnunet-service-testbed_barriers.c */ 910/* end of gnunet-service-testbed_barriers.c */