aboutsummaryrefslogtreecommitdiff
path: root/src/experimentation
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2013-08-01 09:55:19 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2013-08-01 09:55:19 +0000
commitebfff277d665c418845f138aaf2b597ef29624ae (patch)
tree1fa7020c6ce07db88d6cfcba5ce24ba367740966 /src/experimentation
parentc332f5fe5ecbf213955580b0368de1e6c281c19b (diff)
downloadgnunet-ebfff277d665c418845f138aaf2b597ef29624ae.tar.gz
gnunet-ebfff277d665c418845f138aaf2b597ef29624ae.zip
message parsing on receive
Diffstat (limited to 'src/experimentation')
-rw-r--r--src/experimentation/gnunet-daemon-experimentation.h74
-rw-r--r--src/experimentation/gnunet-daemon-experimentation_experiments.c57
-rw-r--r--src/experimentation/gnunet-daemon-experimentation_nodes.c248
3 files changed, 357 insertions, 22 deletions
diff --git a/src/experimentation/gnunet-daemon-experimentation.h b/src/experimentation/gnunet-daemon-experimentation.h
index 052005439..c6fc670f4 100644
--- a/src/experimentation/gnunet-daemon-experimentation.h
+++ b/src/experimentation/gnunet-daemon-experimentation.h
@@ -175,6 +175,8 @@ struct Experimentation_Issuer
175 struct GNUNET_PeerIdentity issuer_id; 175 struct GNUNET_PeerIdentity issuer_id;
176}; 176};
177 177
178GNUNET_NETWORK_STRUCT_BEGIN
179
178/** 180/**
179 * Experimentation request message 181 * Experimentation request message
180 * Used to detect experimentation capability 182 * Used to detect experimentation capability
@@ -208,6 +210,63 @@ struct Experimentation_Response
208 uint32_t issuer_count; 210 uint32_t issuer_count;
209}; 211};
210 212
213
214/**
215 * Experiment start message
216 *
217 * struct is followed by string with length len_name
218 */
219struct GED_start_message
220{
221 struct GNUNET_MessageHeader header;
222
223 /**
224 * String length of experiment name following the struct
225 */
226 uint32_t len_name;
227
228 /* Experiment issuer */
229 struct GNUNET_PeerIdentity issuer;
230
231 /* Experiment version as timestamp of creation */
232 struct GNUNET_TIME_AbsoluteNBO version_nbo;
233};
234
235struct GED_start_ack_message
236{
237 struct GNUNET_MessageHeader header;
238
239 /**
240 * String length of experiment name following the struct
241 */
242 uint32_t len_name;
243
244 /* Experiment issuer */
245 struct GNUNET_PeerIdentity issuer;
246
247 /* Experiment version as timestamp of creation */
248 struct GNUNET_TIME_AbsoluteNBO version_nbo;
249};
250
251struct GED_stop_message
252{
253 struct GNUNET_MessageHeader header;
254
255 /**
256 * String length of experiment name following the struct
257 */
258 uint32_t len_name;
259
260 /* Experiment issuer */
261 struct GNUNET_PeerIdentity issuer;
262
263 /* Experiment version as timestamp of creation */
264 struct GNUNET_TIME_AbsoluteNBO version_nbo;
265};
266
267GNUNET_NETWORK_STRUCT_END
268
269
211int 270int
212GED_nodes_rts (struct Node *n); 271GED_nodes_rts (struct Node *n);
213 272
@@ -273,8 +332,23 @@ int
273GED_experiments_issuer_accepted (struct GNUNET_PeerIdentity *issuer_ID); 332GED_experiments_issuer_accepted (struct GNUNET_PeerIdentity *issuer_ID);
274 333
275 334
335/*
336 * Find an experiment based on issuer name and version
337 *
338 * @param issuer the issuer
339 * @param name experiment name
340 * @param version experiment version
341 * @return the experiment or NULL if not found
342 */
343struct Experiment *
344GED_experiments_find (const struct GNUNET_PeerIdentity *issuer,
345 const char *name,
346 const struct GNUNET_TIME_Absolute version);
347
348
276typedef void (*GNUNET_EXPERIMENTATION_experiments_get_cb) (struct Node *n, struct Experiment *e); 349typedef void (*GNUNET_EXPERIMENTATION_experiments_get_cb) (struct Node *n, struct Experiment *e);
277 350
351
278void 352void
279GED_experiments_get (struct Node *n, 353GED_experiments_get (struct Node *n,
280 struct GNUNET_PeerIdentity *issuer, 354 struct GNUNET_PeerIdentity *issuer,
diff --git a/src/experimentation/gnunet-daemon-experimentation_experiments.c b/src/experimentation/gnunet-daemon-experimentation_experiments.c
index 9e5cfd7e9..28becc42d 100644
--- a/src/experimentation/gnunet-daemon-experimentation_experiments.c
+++ b/src/experimentation/gnunet-daemon-experimentation_experiments.c
@@ -141,12 +141,62 @@ GED_experiments_issuer_accepted (struct GNUNET_PeerIdentity *issuer_ID)
141 return GNUNET_NO; 141 return GNUNET_NO;
142} 142}
143 143
144struct FindCtx
145{
146 const char *name;
147 struct GNUNET_TIME_Absolute version;
148 struct Experiment *res;
149};
150
151static int
152find_it (void *cls,
153 const struct GNUNET_HashCode * key,
154 void *value)
155{
156 struct FindCtx *find_ctx = cls;
157 struct Experiment *e = (struct Experiment *) value;
158
159 if (0 != strcmp(e->name, find_ctx->name))
160 return GNUNET_OK;
161 if (e->version.abs_value != find_ctx->version.abs_value)
162 return GNUNET_OK;
163
164 find_ctx->res = e;
165 return GNUNET_NO;
166}
167
168
169/*
170 * Find an experiment based on issuer name and version
171 *
172 * @param issuer the issuer
173 * @param name experiment name
174 * @param version experiment version
175 * @return the experiment or NULL if not found
176 */
177struct Experiment *
178GED_experiments_find (const struct GNUNET_PeerIdentity *issuer,
179 const char *name,
180 const struct GNUNET_TIME_Absolute version)
181{
182 struct FindCtx find_ctx;
183
184 find_ctx.name = name;
185 find_ctx.version = version;
186 find_ctx.res = NULL;
187
188 GNUNET_CONTAINER_multihashmap_get_multiple (experiments,
189 &issuer->hashPubKey, &find_it, &find_ctx);
190 return find_ctx.res;
191}
192
144struct GetCtx 193struct GetCtx
145{ 194{
146 struct Node *n; 195 struct Node *n;
147 GNUNET_EXPERIMENTATION_experiments_get_cb get_cb; 196 GNUNET_EXPERIMENTATION_experiments_get_cb get_cb;
148}; 197};
149 198
199
150static int 200static int
151get_it (void *cls, 201get_it (void *cls,
152 const struct GNUNET_HashCode * key, 202 const struct GNUNET_HashCode * key,
@@ -160,13 +210,10 @@ get_it (void *cls,
160 return GNUNET_OK; 210 return GNUNET_OK;
161} 211}
162 212
163
164
165
166void 213void
167GED_experiments_get (struct Node *n, 214GED_experiments_get (struct Node *n,
168 struct GNUNET_PeerIdentity *issuer, 215 struct GNUNET_PeerIdentity *issuer,
169 GNUNET_EXPERIMENTATION_experiments_get_cb get_cb) 216 GNUNET_EXPERIMENTATION_experiments_get_cb get_cb)
170{ 217{
171 struct GetCtx get_ctx; 218 struct GetCtx get_ctx;
172 219
diff --git a/src/experimentation/gnunet-daemon-experimentation_nodes.c b/src/experimentation/gnunet-daemon-experimentation_nodes.c
index 667c9da57..58cc2e84f 100644
--- a/src/experimentation/gnunet-daemon-experimentation_nodes.c
+++ b/src/experimentation/gnunet-daemon-experimentation_nodes.c
@@ -32,6 +32,7 @@
32#include "gnunet-daemon-experimentation.h" 32#include "gnunet-daemon-experimentation.h"
33 33
34 34
35#define FAST_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
35/** 36/**
36 * Core handle 37 * Core handle
37 */ 38 */
@@ -320,6 +321,34 @@ get_experiments_cb (struct Node *n, struct Experiment *e)
320 counter ++; 321 counter ++;
321} 322}
322 323
324struct Node *
325get_node (const struct GNUNET_PeerIdentity *id)
326{
327 struct Node * res;
328 struct Node * tmp;
329
330 res = NULL;
331 tmp = NULL;
332 tmp = GNUNET_CONTAINER_multihashmap_get (nodes_active, &id->hashPubKey);
333 if (res == NULL)
334 res = tmp;
335
336 tmp = GNUNET_CONTAINER_multihashmap_get (nodes_inactive, &id->hashPubKey);
337 if (res == NULL)
338 res = tmp;
339 else
340 GNUNET_break (0); /* Multiple instances */
341
342 tmp = GNUNET_CONTAINER_multihashmap_get (nodes_requested, &id->hashPubKey);
343 if (res == NULL)
344 res = tmp;
345 else
346 GNUNET_break (0); /* Multiple instances */
347
348 return res;
349}
350
351
323/** 352/**
324 * Set a specific node as active 353 * Set a specific node as active
325 * 354 *
@@ -555,7 +584,68 @@ static void handle_response (const struct GNUNET_PeerIdentity *peer,
555static void handle_start (const struct GNUNET_PeerIdentity *peer, 584static void handle_start (const struct GNUNET_PeerIdentity *peer,
556 const struct GNUNET_MessageHeader *message) 585 const struct GNUNET_MessageHeader *message)
557{ 586{
558 GED_scheduler_handle_start (NULL, NULL); 587 uint16_t size;
588 uint32_t name_len;
589 const struct GED_start_message *msg;
590 const char *name;
591 struct Node *n;
592 struct Experiment *e;
593
594 if (NULL == peer)
595 {
596 GNUNET_break (0);
597 return;
598 }
599 if (NULL == message)
600 {
601 GNUNET_break (0);
602 return;
603 }
604
605 size = ntohs (message->size);
606 if (size < sizeof (struct GED_start_message))
607 {
608 GNUNET_break (0);
609 return;
610 }
611 msg = (const struct GED_start_message *) message;
612 name_len = ntohl (msg->len_name);
613 if (size != sizeof (struct GED_start_message) + name_len)
614 {
615 GNUNET_break (0);
616 return;
617 }
618
619 n = get_node (peer);
620 if (NULL == n)
621 {
622 GNUNET_break (0);
623 return;
624 }
625 name = (const char *) &msg[1];
626 if (name[name_len-1] != '\0')
627 {
628 GNUNET_break (0);
629 return;
630 }
631
632 if (name_len != strlen (name) + 1)
633 {
634 GNUNET_break (0);
635 return;
636 }
637
638 e = GED_experiments_find (&msg->issuer, name, GNUNET_TIME_absolute_ntoh(msg->version_nbo));
639 if (NULL == e)
640 {
641 GNUNET_break (0);
642 return;
643 }
644
645 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Received %s message from peer %s for experiment `%s'\n"),
646 "START", GNUNET_i2s (peer), name);
647
648 GED_scheduler_handle_start (n, e);
559} 649}
560 650
561/** 651/**
@@ -567,7 +657,67 @@ static void handle_start (const struct GNUNET_PeerIdentity *peer,
567static void handle_start_ack (const struct GNUNET_PeerIdentity *peer, 657static void handle_start_ack (const struct GNUNET_PeerIdentity *peer,
568 const struct GNUNET_MessageHeader *message) 658 const struct GNUNET_MessageHeader *message)
569{ 659{
570 GED_scheduler_handle_start_ack (NULL, NULL); 660 uint16_t size;
661 uint32_t name_len;
662 const struct GED_start_ack_message *msg;
663 const char *name;
664 struct Node *n;
665 struct Experiment *e;
666
667 if (NULL == peer)
668 {
669 GNUNET_break (0);
670 return;
671 }
672 if (NULL == message)
673 {
674 GNUNET_break (0);
675 return;
676 }
677
678 size = ntohs (message->size);
679 if (size < sizeof (struct GED_start_ack_message))
680 {
681 GNUNET_break (0);
682 return;
683 }
684 msg = (const struct GED_start_ack_message *) message;
685 name_len = ntohl (msg->len_name);
686 if (size != sizeof (struct GED_start_message) + name_len)
687 {
688 GNUNET_break (0);
689 return;
690 }
691
692 n = get_node (peer);
693 if (NULL == n)
694 {
695 GNUNET_break (0);
696 return;
697 }
698 name = (const char *) &msg[1];
699 if (name[name_len-1] != '\0')
700 {
701 GNUNET_break (0);
702 return;
703 }
704
705 if (name_len != strlen (name) + 1)
706 {
707 GNUNET_break (0);
708 return;
709 }
710
711 e = GED_experiments_find (&msg->issuer, name, GNUNET_TIME_absolute_ntoh(msg->version_nbo));
712 if (NULL == e)
713 {
714 GNUNET_break (0);
715 return;
716 }
717
718 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Received %s message from peer %s for experiment `%s'\n"),
719 "START_ACK", GNUNET_i2s (peer), name);
720 GED_scheduler_handle_start_ack (n, e);
571} 721}
572 722
573/** 723/**
@@ -577,9 +727,69 @@ static void handle_start_ack (const struct GNUNET_PeerIdentity *peer,
577 * @param message the message 727 * @param message the message
578 */ 728 */
579static void handle_stop (const struct GNUNET_PeerIdentity *peer, 729static void handle_stop (const struct GNUNET_PeerIdentity *peer,
580 const struct GNUNET_MessageHeader *message) 730 const struct GNUNET_MessageHeader *message)
581{ 731{
582 GED_scheduler_handle_stop (NULL, NULL); 732 uint16_t size;
733 uint32_t name_len;
734 const struct GED_stop_message *msg;
735 const char *name;
736 struct Node *n;
737 struct Experiment *e;
738
739 if (NULL == peer)
740 {
741 GNUNET_break (0);
742 return;
743 }
744 if (NULL == message)
745 {
746 GNUNET_break (0);
747 return;
748 }
749
750 size = ntohs (message->size);
751 if (size < sizeof (struct GED_stop_message))
752 {
753 GNUNET_break (0);
754 return;
755 }
756 msg = (const struct GED_stop_message *) message;
757 name_len = ntohl (msg->len_name);
758 if (size != sizeof (struct GED_start_message) + name_len)
759 {
760 GNUNET_break (0);
761 return;
762 }
763
764 n = get_node (peer);
765 if (NULL == n)
766 {
767 GNUNET_break (0);
768 return;
769 }
770 name = (const char *) &msg[1];
771 if (name[name_len-1] != '\0')
772 {
773 GNUNET_break (0);
774 return;
775 }
776
777 if (name_len != strlen (name) + 1)
778 {
779 GNUNET_break (0);
780 return;
781 }
782
783 e = GED_experiments_find (&msg->issuer, name, GNUNET_TIME_absolute_ntoh(msg->version_nbo));
784 if (NULL == e)
785 {
786 GNUNET_break (0);
787 return;
788 }
789
790 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Received %s message from peer %s for experiment `%s'\n"),
791 "STOP", GNUNET_i2s (peer), name);
792 GED_scheduler_handle_stop (n, e);
583} 793}
584 794
585/** 795/**
@@ -671,13 +881,6 @@ core_receive_handler (void *cls,
671 return GNUNET_OK; 881 return GNUNET_OK;
672} 882}
673 883
674#define FAST_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
675
676struct GNUNET_EXPERIMENTATION_start_message
677{
678 struct GNUNET_MessageHeader header;
679};
680
681struct ExperimentStartCtx 884struct ExperimentStartCtx
682{ 885{
683 struct ExperimentStartCtx *prev; 886 struct ExperimentStartCtx *prev;
@@ -690,7 +893,9 @@ struct ExperimentStartCtx
690size_t node_experiment_start_cb (void *cls, size_t bufsize, void *buf) 893size_t node_experiment_start_cb (void *cls, size_t bufsize, void *buf)
691{ 894{
692 struct ExperimentStartCtx *e_ctx = cls; 895 struct ExperimentStartCtx *e_ctx = cls;
693 struct GNUNET_EXPERIMENTATION_start_message msg; 896 struct GED_start_message *msg;
897 size_t name_len;
898 size_t size;
694 899
695 GNUNET_CONTAINER_DLL_remove (e_ctx->n->e_req_head, e_ctx->n->e_req_tail, e_ctx); 900 GNUNET_CONTAINER_DLL_remove (e_ctx->n->e_req_head, e_ctx->n->e_req_tail, e_ctx);
696 e_ctx->n->cth = NULL; 901 e_ctx->n->cth = NULL;
@@ -700,15 +905,24 @@ size_t node_experiment_start_cb (void *cls, size_t bufsize, void *buf)
700 return 0; 905 return 0;
701 } 906 }
702 907
703 size_t size = sizeof (struct GNUNET_EXPERIMENTATION_start_message); 908 name_len = strlen(e_ctx->e->name) + 1;
704 msg.header.size = htons (size); 909 size = sizeof (struct GED_start_message) + name_len;
705 msg.header.type = htons (GNUNET_MESSAGE_TYPE_EXPERIMENTATION_START);
706 910
707 memcpy (buf, &msg, size); 911 msg = GNUNET_malloc (size);
912 msg->header.size = htons (size);
913 msg->header.type = htons (GNUNET_MESSAGE_TYPE_EXPERIMENTATION_START);
914 msg->issuer = e_ctx->e->issuer;
915 msg->version_nbo = GNUNET_TIME_absolute_hton(e_ctx->e->version);
916 msg->len_name = htonl (name_len);
917 memcpy (&msg[1], e_ctx->e->name, name_len);
918
919 memcpy (buf, msg, size);
920 GNUNET_free (msg);
708 GNUNET_free (e_ctx); 921 GNUNET_free (e_ctx);
709 return size; 922 return size;
710} 923}
711 924
925
712int 926int
713GED_nodes_rts (struct Node *n) 927GED_nodes_rts (struct Node *n)
714{ 928{
@@ -742,7 +956,7 @@ GED_nodes_request_start (struct Node *n, struct Experiment *e)
742 e_ctx->n = n; 956 e_ctx->n = n;
743 e_ctx->e = e; 957 e_ctx->e = e;
744 n->cth = GNUNET_CORE_notify_transmit_ready (ch, GNUNET_NO, 0, FAST_TIMEOUT, &n->id, 958 n->cth = GNUNET_CORE_notify_transmit_ready (ch, GNUNET_NO, 0, FAST_TIMEOUT, &n->id,
745 sizeof (struct GNUNET_EXPERIMENTATION_start_message), 959 sizeof (struct GED_start_message) + strlen (e->name) + 1,
746 &node_experiment_start_cb, e_ctx); 960 &node_experiment_start_cb, e_ctx);
747 if (NULL == n->cth) 961 if (NULL == n->cth)
748 { 962 {